SAS V9.1.3 - 组合%INC和CALL EXECUTE时出错

时间:2010-03-03 12:09:08

标签: include macros sas execute

我收到一些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错过了作业,我该怎么办呢?

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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
*/