2

我收到一些 SAS v9.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 生成 %inc problem2 而不是 %report1,导致 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并抱怨,因为看起来您正在将文本(&email)与数字(1)进行比较。

%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 回答