SAS:从另一个宏调用一个宏...宏定义的顺序

发布于 2024-07-13 02:42:16 字数 220 浏览 7 评论 0原文

在我的代码中我有几个宏。 宏 A 是主宏。 然后宏 A 调用宏 B,宏 B 又调用宏 C。

在 SAS 中,我是否必须按向后的顺序定义它们? 换句话说,我是否必须先定义宏C,然后定义宏B,最后定义宏A? 还是因为 SAS 在实际执行命令来运行宏之前读取了所有代码,所以这很重要吗? 就此而言,我可以发出命令来运行宏作为代码中的第一个语句,然后在命令下面定义宏吗?

谢谢!

In my code I have several macros. Macro A is the main macro. Macro A then calls macro B which in turn calls macro C.

In SAS, do I have to define them in backwards order? In other words, do I have to define macro C first, then macro B, then macro A last? Or does it matter since SAS reads all the code in before it actually hits the command to run the macros? For that matter, can I issue the command to run the macro as the first statement in my code and then define the macros below the command?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

表情可笑 2024-07-20 02:42:16

首先,您必须在调用宏之前定义它。

其次,只要您事先加载了宏,那么在哪里调用宏并不重要。

详细说明您的问题:自动调用库是您的朋友。 如果 SAS 管理员不允许您将宏放入自动调用库中,您可以像这样附加自动调用:

filename mymacros 'c:\mysas'; 
/*this defines the directory you have stored your macros*/

options sasautos=(sasautos mymacros) mautosource; 

First, you must define a macro before it is called.

Second, it doesn't matter where the macro is invoked as long as you have loaded it before-hand.

To elaborate on your issue: The autocall library is your friend. If you SAS administrator won't allow you to put your macros in the autocall library, you can append the autocall like so:

filename mymacros 'c:\mysas'; 
/*this defines the directory you have stored your macros*/

options sasautos=(sasautos mymacros) mautosource; 
醉城メ夜风 2024-07-20 02:42:16

宏必须在调用之前定义。 出于性能原因,最好不要在另一个宏中定义宏——如果这样做,那么每次调用外部宏时都会重新定义它。 以下工作正常:

%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
*/

a macro has to be defined before it is called. for performance reasons, it is best not to define a macro inside another -- if you do so, then it will be re-defined every time you call the outer macro. the following works fine:

%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
*/
巡山小妖精 2024-07-20 02:42:16

您必须在调用之前定义宏,因此带有“%A”的行需要遵循宏 A 的定义。其他宏定义的顺序并不重要,只要它们在调用之前定义即可。 通常,在我的程序中,我会设置一个像您所描述的那样的主宏,然后程序的最后一行调用该宏。

另一个需要考虑的选择是设置一个宏自动调用库,其中包含许多宏的定义。 这最适合可重用的宏,这样您就不必在每个程序中重新定义它们。

You must define a macro before it is called, so the line with "%A" would need to follow the definition of macro A. The order of the other macro definitions does not matter, as long as they are defined before they are called. Typically in my programs I set up a main macro like you describe, then the last line of the program calls this macro.

Another option to consider is to set up a macro autocall library, which contains the definitions of many macros. This works best for reusable macros, so that you do not have to redefine them in each program.

酒解孤独 2024-07-20 02:42:16

SAS 中的宏代码有两个方面需要定义:编译的宏代码和宏参数:

宏代码:

宏代码本身非常简单,当 %macro遇到 标记时,SAS 系统开始编译 SAS 宏并继续编译,直到遇到 %mend 标记。 您可能遇到的唯一真正问题是,如果您更新了宏代码并且在执行之前没有重新编译它 - 在这些情况下,它仍然会运行宏库中的旧版本。 通过扩展,如果您尝试编译一个调用另一个尚未定义的宏的宏,那么您将收到错误。 由于这些原因,需要按照调用顺序对它们进行编程(如下例所示:%level3 位于 %level2 之前,%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 ;

查看日志时的注意事项:

  • % 之外level3, &I 返回宏变量的警告
    不存在
  • 在 %level3 中,当调用 &G1 时,它返回存储在中的值
    %level3 的本地范围。一旦超出 %level3,该值将返回
    到全局存储的值

There are two aspects of macro code in SAS to be defined: the macro code that gets compiled and the macro parameters:

Macro code:

The macro code itself is very simple in that when the %macro token is encountered the SAS system starts to compile a SAS macro and keeps compiling until it hits a %mend token. The only real problems you can come up against is if you updated macro code and don’t recompile it before executing it – in these situations it will still run the old version it has in the macro library. By extension, if you try to compile a macro that calls another macro which hasn’t already been defined then you will get an error. For these reasons, they need to be programmed in the order in which they are called (as shown in below example: %level3 comes before %level2, which comes before %level1)

Macro variables:
When defining macro variables there are two scopes: Global and Local. Once defined, global variables can be accessed anywhere and at any time. However, local variables only exist locally during the execution of the macro in which it has been defined. By extension, if the macro where the local variable has been defined calls any other macros, the local macro variable will still be accessible:

Working Example:

In the following example, the macros are defined in reverse order to prevent SAS returning an Apparent invocation of macro warning.

The below diagram illustrates the structure of the following macros in the following example:

|-----------------------------|
|GLOBAL                       |
|  |------------------------| |
|  |LEVEL1                  | |
|  |  |-------------------| | |
|  |  |LEVEL2             | | |
|  |  |  |--------------| | | |
|  |  |  |  LEVEL3      | | | |
|  |  |  |--------------| | | |
|  |  |-------------------| | |
|  |------------------------| |
|-----------------------------|

Compile the nested macros:

 %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 ;

Compile the top level macro (which in turn calls the above two macros) and run it:

%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 ;

Points to note when reviewing the log:

  • Outside of %level3, &I returns a warning that the macro variable does
    not exist
  • Within %level3, when &G1 is called, it returns the value stored in
    the local scope of %level3.Once outside of %level3, the value returns
    to the value stored globally
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文