我在SAS中多次运行宏,如下所示:
%mymac(a,b);
%mymac(a,c);
.
%mymac(a,a)
%mymac(a,w);
.
我的程序/宏类似于:
/* begin program here */
data original_data;
set mylib.mydata;
run;
%macro mymac(x,y);
data mydata1;
set original_data;
where school_district="&x";
run;
proc means data=mydata1;
var income;
run;
%mend mymac;
我意识到我忘记了分号(如(a,a)中的分号)并且SAS似乎并不介意。它运行所有的宏调用没有问题。当我添加分号时,我比较了输出,我看不出有什么区别。
这是正常的,SAS没有给出缺少分号的错误吗?
答案 0 :(得分:4)
宏调用需要 分号。
通常它们被包括在内,因为人们习惯于将分号视为“终止声明”或结束行的方式。我个人更愿意尽可能包含它们,因为我相信它使我的代码更具可读性。
请记住,宏只是评估自己并返回它们解决的任何内容,这可能是一个看起来像数字,字符串或其他任何内容的代码块......
以没有使用分号的示例为例:
%macro field_list();
name,
age,
sex,
height
%mend;
proc sql;
select %field_list()
from sashelp.class
;
quit;
尝试在启用了option mprint;
的计算机上运行它。运行宏的结果只返回其中的代码块。这导致执行以下代码:
proc sql;
select name, age, sex, height
from sashelp.class
;
quit;
如果在调用我们的宏之后我们有一个分号,那么SAS尝试运行的代码将包含分号,这将是无效的语法,如下所示(注意高度后的分号):
proc sql;
select name, age, sex, height ;
from sashelp.class
;
quit;
这是因为调用宏不需要分号,因此它只会被遗忘并包含在执行步骤中。
当您在上面给出的示例中调用宏时,可以包含分号,因为您的宏是完全自包含的步骤。在开放代码中,如下所示有无关的分号是没有害处的:
%macro example2(inDS=, outDs=);
data &outDs;
set &inDs;
run;
%mend;
%example2(inDS=sashelp.class, outDs=tmp_class);
这基本上评估为:
data tmp_class;
set sashelp.class;
run;;
请注意我们通话结尾留下的额外分号?我们可以拥有我们想要的尽可能多的代码仍然可以正常运行,即:
%example2(inDS=sashelp.class, outDs=tmp_class);;;;;;
解析为:
data tmp_class;
set sashelp.class;
run;;;;;;;
由于它是有效的语法,因此仍可正常运行。
答案 1 :(得分:3)
通常很好。关于SAS Macro的主要理解是它是一个代码生成工具,而不是真正的编程语言。虽然%my_mac(x,y);
看起来像是一种类似C语言的传统函数调用,但您希望以;
结束每个语句,此处终止;
没有实际意义。相反,它是在%my_mac(x,y)
内部生成的SAS代码。在您的情况下,该代码是语法SAS,并且很好。如果您在心理上将%my_mac(x,y)
来电替换为其生成的代码(即data mydata.....run;
),即使没有%my_mac(x,y)
;
,也会看到它是语法上的。如果您改为编写%my_mac(x,y);
,它只会生成data mydate.....run;;
,这很好,但;
是多余的。
事实上,跳过分号也是一个拥有宏的返回值的黑客。例如:
%MACRO x_plus_n (x = , y= );
%SYSEVALF (&x + &y)
%MEND;
%LET x = 3 ;
%LET y = 4 ;
%LET z = %x_plus_n (x = &x , y= &y) is the result;
%PUT ------------- &z;
注意%SYSEVALF行上缺少;
。这允许宏在%LET z = ....
开始的行结束之前不会终止,其中有;
。 x_plus_n
创建的输出成为宏的一种返回值。
答案 2 :(得分:2)
宏只是文本替换。它们本身通常不是可执行语句(尽管它们有时可以使用%SYSFUNC
执行语句)。因此,在宏调用之后不需要分号,除非在宏中包含的文本之后需要分号(并且实际上不包含在宏本身中)。
IE:
%macro test;
proc freq data=sashelp.class;
run
%mend test;
必须以
执行%test;
因为run
没有终端分号。如果你在宏run
之后放了一个分号,那么你可以在没有分号的情况下将其作为%test
运行。
记住第一句话:宏只是文本替换。无论宏生成什么文本,都会进入SAS程序并执行,就好像你输入它一样(也许你使用%do i=1 %to 100;
- 所以它会放置100个循环内容的副本 - 但就好像你你自己打了100个)。因此,对;
的需求取决于您是否需要输入它。