SAS:从一个宏调用另一个宏…宏定义的顺序
在我的代码中有几个宏。宏A是主宏。然后宏A调用宏B,宏B又调用宏C 在SAS中,是否必须按向后顺序定义它们?换句话说,我必须先定义宏C,然后定义宏B,最后定义宏A吗?还是因为SAS在实际执行运行宏的命令之前读取了所有代码,所以这很重要?就此而言,我是否可以发出命令,将宏作为代码中的第一条语句运行,然后在命令下面定义宏SAS:从一个宏调用另一个宏…宏定义的顺序,sas,sas-macro,Sas,Sas Macro,在我的代码中有几个宏。宏A是主宏。然后宏A调用宏B,宏B又调用宏C 在SAS中,是否必须按向后顺序定义它们?换句话说,我必须先定义宏C,然后定义宏B,最后定义宏A吗?还是因为SAS在实际执行运行宏的命令之前读取了所有代码,所以这很重要?就此而言,我是否可以发出命令,将宏作为代码中的第一条语句运行,然后在命令下面定义宏 谢谢 您必须在调用宏之前定义它,因此带有“%a”的行需要遵循宏a的定义。其他宏定义的顺序无关紧要,只要在调用之前定义它们即可。通常,在我的程序中,我设置了一个如您所述的主宏,然后程
谢谢 您必须在调用宏之前定义它,因此带有“%a”的行需要遵循宏a的定义。其他宏定义的顺序无关紧要,只要在调用之前定义它们即可。通常,在我的程序中,我设置了一个如您所述的主宏,然后程序的最后一行调用此宏
另一个要考虑的选项是建立一个宏AutoCar库,它包含许多宏的定义。这最适用于可重用宏,因此您不必在每个程序中重新定义它们。
首先,您必须在调用宏之前定义宏 其次,调用宏的位置无关紧要,只要您事先加载了宏即可 详细说明您的问题:autocall库是您的朋友。如果SAS管理员不允许您将宏放入自动调用库,您可以像这样附加自动调用:filename mymacros 'c:\mysas';
/*this defines the directory you have stored your macros*/
options sasautos=(sasautos mymacros) mautosource;
在调用宏之前,必须先定义宏。出于性能原因,最好不要在另一个宏中定义宏——如果这样做,那么每次调用外部宏时都会重新定义它。以下工作很好:
%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
*/
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 ;
查看日志时要注意的事项:
- 在%level3之外,&I返回宏变量不存在的警告 不存在
- 在%level3中,调用&G1时,它返回存储在中的值 %level3的本地范围。一旦超出%level3,该值将返回 到全局存储的值
%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 ;