When the macro processor executes
a macro program statement that can create a macro variable, the macro
processor creates the variable in the local symbol table if no macro
variable with the same name is available to it. Consider the following
example:
%let new=inventry;
%macro name2;
%let new=report;
%let old=warehse;
%mend name2;
%name2
data &new;
set &old;
run;
After NAME2 executes,
the SAS compiler sees the following statements:
data report;
set &old;
run;
The macro processor
encounters the reference &OLD after macro NAME2 has finished executing.
Thus, the macro variable OLD no longer exists. The macro processor
is not able to resolve the reference and issues a warning message.
The following figure
illustrates the contents of the global and local symbol tables at
various stages.
But suppose you place
the SAS statements inside the macro NAME2, as in the following program:
%let new=inventry;
%macro name2;
%let new=report;
%let old=warehse;
data &new;
set &old;
run;
%mend name2;
%name2
In this case, the macro
processor generates the SET statement during the execution of NAME2,
and it locates OLD in NAME2's local symbol table. Therefore, executing
the macro produces the following statements:
data report;
set warehse;
run;
The same rule applies
regardless of how many levels of nesting exist. Consider the following
example:
%let new=inventry;
%macro conditn;
%let old=sales;
%let cond=cases>0;
%mend conditn;
%macro name3;
%let new=report;
%let old=warehse;
%conditn
data &new;
set &old;
if &cond;
run;
%mend name3;
%name3
The macro processor
generates these statements:
data report;
set sales;
if &cond;
run;
CONDITN finishes executing
before the macro processor reaches the reference &COND, so no
variable named COND exists when the macro processor attempts to resolve
the reference. Thus, the macro processor issues a warning message
and generates the unresolved reference as part of the constant text
and issues a warning message. The following figure shows the symbol
tables at each step.
Notice that the placement
of a macro invocation is what creates a nested scope, not the placement
of the macro definition. For example, invoking CONDITN from within
NAME3 creates the nested scope. It is not necessary to define CONDITN
within NAME3.