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