2

一部のSASv9.1.3コードで解決エラーが発生します。

これは、.txtファイル(problem2.txtと呼ばれる)に保存し、%INCを使用してSASに取り込むコードです。

%macro email020;                  
   %if &email = 1 %then %do;       
     %put THIS RESOLVED AT 1;      
   %end;                           
   %else %if &email = 2 %then %do; 
     %put THIS RESOVLED AT 2;      
   %end;                           
   %put _user_;                    
%mend email020;                   

%email020; 

次に、これがメインコードです。

filename problem2 'C:\Documents and Settings\Mark\My Documents\problem2.txt';

%macro report1;                            
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2 (inc);                            
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

data test;                                 
  run = 'YES';                             
run;                                       

data _null_;                               
  set test; 
  call execute("%report1");  
  call execute("%report2");  
run;

ログは次のことを示しています。

NOTE: CALL EXECUTE generated line.
1   +  %inc problem2;
MLOGIC(EMAIL020):  Beginning execution.

WARNING: Apparent symbolic reference EMAIL not resolved.

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: &email = 1

ERROR: The macro EMAIL020 will stop executing.

MLOGIC(EMAIL020):  Ending execution.

したがって、問題は、CALL EXECUTEが%report1ではなく%incproblem2を生成し、SASが割り当てを見逃す原因となる理由と、それに対して何ができるかということです。

4

2 に答える 2

2

マクロ変数スコープの問題のようです。試す:

%macro report1;   
  %global email; 
  %let email = 1;
  %inc problem2;
%mend report1;                             

%macro report2;            
%global email; 
  %let email = 2;                          
  %inc problem2;
%mend report2;                             

ただし、グローバルマクロ変数を使用するよりもemail、パラメータとして渡す方が良いと思います。%email020また、ネストされたマクロ定義の使用は避けたいと思います。

マクロ変数のスコープに関するより多くのデータを取得するには、マクロの実行中に Dictionary.macros ビューを照会できます。で Dictionary.macros の説明を取得できます

proc sql;
    describe table dictionary.macros;
quit;
于 2010-03-04T08:51:46.600 に答える
1

%includeマクロ呼び出しではなく、外部ファイルからのコードを含めるための一種のコンパイラ ディレクティブです。マクロ%report1がコンパイルされるとき、マクロ変数はありませんemail(マクロが以前に実行されたことがないため)。したがって、参照はそのまま残り&emailます。次に、テキスト( )と数値( )を比較しているように見えるため、暗黙的なもの%eval()は見&email = 1て文句を言います。&email1

の導入は、%globalできれば避けるべきです。私は%include完全に廃止します。はるかに簡単です。以下は次のとおりです。:-)

%macro doSomething(email=);                  
  %if &email = a@b.c %then %do;       
    %put THIS RESOLVED AT 1;      
  %end; %else %if &email = d@e.f %then %do; 
    %put THIS RESOVLED AT 2;      
  %end;                           
  %put _user_;                    
%mend doSomething;                   


data emails;
  email="a@b.c"; output;
  email="d@e.f"; output;
run;

data _null_;
  set emails;
  call execute(catx(email, '%doSomething(email=', ')'));
run;

/* on log
THIS RESOLVED AT 1
DOSOMETHING EMAIL a@b.c
THIS RESOVLED AT 2
DOSOMETHING EMAIL d@e.f
*/
于 2010-03-11T21:11:34.253 に答える