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