在我的代码中,我有几个宏。宏A是主宏。宏A然后调用宏B,宏B又调用宏C.
在SAS中,我是否必须按向后顺序定义它们?换句话说,我必须首先定义宏C,然后定义宏B,然后定义宏A吗?或者它是否重要,因为SAS在实际命中运行宏之前读取所有代码?就此而言,我可以发出命令将宏作为代码中的第一个语句运行,然后在命令下面定义宏吗?
谢谢!
答案 0 :(得分:3)
首先,您必须在调用宏之前定义它。
其次,只要您在事先加载宏,调用宏的位置并不重要。
详细说明您的问题:自动调用库是您的朋友。如果您的SAS管理员不允许您将宏放入自动调用库中,则可以像这样附加自动调用:
filename mymacros 'c:\mysas';
/*this defines the directory you have stored your macros*/
options sasautos=(sasautos mymacros) mautosource;
答案 1 :(得分:3)
在调用宏之前必须定义一个宏。出于性能原因,最好不要在另一个宏中定义宏 - 如果这样做,那么每次调用外部宏时都会重新定义它。以下工作正常:
%macro a;
%put a;
%b
%mend a;
%macro b;
%put b;
%c
%mend b;
%macro c;
%put c;
%mend c;
%*-- %a is main --*;
%a
/* on log
a
b
c
*/
答案 2 :(得分:1)
您必须在调用宏之前定义宏,因此带有“%A”的行需要遵循宏A的定义。其他宏定义的顺序无关紧要,只要它们在它们之前定义叫做。通常在我的程序中,我设置了一个像你描述的主宏,然后程序的最后一行调用这个宏。
要考虑的另一个选择是设置宏自动调用库,其中包含许多宏的定义。这最适用于可重用的宏,因此您不必在每个程序中重新定义它们。
答案 3 :(得分:0)
要定义SAS中的宏代码有两个方面:编译的宏代码和宏参数:
宏代码:
宏代码本身非常简单,因为当遇到%macro
令牌时,SAS系统开始编译SAS宏并继续编译,直到它到达%mend
令牌。您可以遇到的唯一真正问题是,如果您更新宏代码并且在执行之前不重新编译它 - 在这些情况下它仍将运行它在宏库中的旧版本。通过扩展,如果您尝试编译一个调用另一个尚未定义的宏的宏,那么您将收到错误。由于这些原因,它们需要按照调用它们的顺序进行编程(如下例所示:%level3出现在%level2之前,它出现在%level1之前)
宏变量: 定义宏变量时,有两个范围:全局和本地。定义后,可以随时随地访问全局变量。但是,局部变量仅在执行已定义的宏期间本地存在。通过扩展,如果已定义局部变量的宏调用任何其他宏,则仍可访问本地宏变量:
工作示例:
在以下示例中,宏以相反顺序定义,以防止SAS返回明显调用宏警告。
下图说明了以下示例中以下宏的结构:
|-----------------------------|
|GLOBAL |
| |------------------------| |
| |LEVEL1 | |
| | |-------------------| | |
| | |LEVEL2 | | |
| | | |--------------| | | |
| | | | LEVEL3 | | | |
| | | |--------------| | | |
| | |-------------------| | |
| |------------------------| |
|-----------------------------|
编译嵌套宏:
%macro level3 ;
%put **** START LEVEL3 **** ;
%local G1;
%let G1=Local ;
%do i=1 %to 2 ;
%put In the macro do loop I=&i ;
%end ;
%put The value of I at level3 is: &I ;
%put Are we accessing global or local G1 variable here: &G1 ;
%put **** END LEVEL3 ****;
%mend level3 ;
%macro level2 ;
%put **** START LEVEL2 **** ;
%*global L1 ; *<-- this would produce an error because the variable name has already been added to the local scope in %level1 ;
%put Are we accessing global or local G1 variable here: &G1 ;
%put Can we access local variables here: &L1 ;
%level3 ;
%put The value of I in level2 is: &I ;
%put **** END LEVEL2 ****;
%mend level2 ;
编译顶级宏(进而调用上面两个宏)并运行它:
%let G1=Global;
%macro level1 ;
%put **** START LEVEL1 **** ;
%let L1=Yes;
%put Are we accessing global or local G1 variable here: &G1 ;
%put Can we access local variables here: &L1 ;
%level2 ;
%put The value of I outside of the local macro is: &I ;
%put Are we accessing global or local G1 variable here: &G1 ;
%put **** END LEVEL1 ****;
%mend level1 ;
%level1 ;
查看日志时需要注意的事项: