数据步内的宏执行

Macro execution inside data step

我有以下将在数据步骤中使用的宏:

%global var3;

%macro add(var1,var2);
    %let var3 = %eval(&var1+&var2);
%mend;

我不明白以下数据步骤的结果:

%let var3 = 2;

data test;
    put "The value of var3 is &var3";
    x = 3 - &var3;
    %add(7,3);
    %put &=var3;
run;

据我了解,宏语句是在编译数据步骤之前执行的。所以在这种情况下宏 %add 首先执行,然后执行 %put 语句。但是,x 的值为 1,而不是 -7。并且还把语句打印 var3 的值是 2,而不是 10。我很困惑。

让我们看看会发生什么。

 69         %global var3;
 70         
 71         %macro add(var1,var2);
 72             %let var3 = %eval(&var1+&var2);
 73         %mend;
 74         
 75         %let var3 = 2;
 76         options symbolgen mprint;
 77         data test;
 SYMBOLGEN:  Macro variable VAR3 resolves to 2
 78             put "The value of var3 is &var3";
 79             x = 3 - &var3;
 SYMBOLGEN:  Macro variable VAR3 resolves to 2
 80             %add(7,3);
 SYMBOLGEN:  Macro variable VAR1 resolves to 7
 SYMBOLGEN:  Macro variable VAR2 resolves to 3
 81             %put &=var3;
 SYMBOLGEN:  Macro variable VAR3 resolves to 10
 VAR3=10
 82         run;
 
 The value of var3 is 2

所以,SAS 转到 运行 宏传递,就像你在数据步骤编译之前所说的那样,并将代码变成这样...

data test;
  put "The value of var3 is 2";
  x = 3 - 2;
  %let var3 = %eval(7+3);
  %put 10;
run;

你说得对,SAS 确实在编译之前处理了宏语言,但这并不意味着它发生在 SAS 开始为编译准备数据步骤之前。宏语言传递创建最后的数据步骤,但它仍然按顺序发生 - 所以 SAS 查看第 77 行,没有看到任何宏变量,将其完成;它查看第 78 行,看到 &var3,将其转换为 2,最终确定该行;看第79行等