Kurt has identified the problem, I want to share an example. Suppose you have macros OUTER and INNER where OUTER invokes INNER. You want to have OUTER loop 2 times, and INNER loop 3 times per iteration of OUTER.
If you code it like:
%macro outer(n=) ;
%do i=1 %to &n ;
%put %nrstr(%%)&sysmacroname ;
%put _user_ ;
%put ;
%inner(n=3) ;
%end ;
%mend outer ;
%macro inner(n=) ;
%do i=1 %to &n ;
%put %nrstr(%%)&sysmacroname ;
%put _user_ ;
%put ;
%end ;
%mend inner ;
%outer(n=2)
Your log will show that OUTER is loops once, not twice as intended. This is the problem you're having:
22 %outer(n=2)
%OUTER
OUTER I 1
OUTER N 2
%INNER
INNER N 3
OUTER I 1
OUTER N 2
%INNER
INNER N 3
OUTER I 2
OUTER N 2
%INNER
INNER N 3
OUTER I 3
OUTER N 2
When OUTER executes, it creates the macro variables i and N.
When INNER executes, it creates a new macro variable N which is a different macro variable than the variable N which exists in outer. It does this because N is defined as macro parameter to INNER.
But when the %DO loop in INNER executes, it does NOT create a new macro variable i for INNER. Instead it uses the macro variable i that already exists in OUTER. So this is a naming collision. INNER has changed the values of a macro variable that belongs to OUTER. And because INNER loops three times, you end up with the macro variable i having the value of 3. Then the %DO loop in OUTER does not loop a second time, because i is already 3.
The way to avoid this problem is to declare the macro variable i to be local in INNER. That way when INNER executes, the %LOCAL statement will create a new local macro variable i for INNER that is separate from the macro variable i in OUTER.
%macro outer(n=) ;
%local i ;
%do i=1 %to &n ;
%put %nrstr(%%)&sysmacroname ;
%put _user_ ;
%put ;
%inner(n=3) ;
%end ;
%mend outer ;
%macro inner(n=) ;
%local i;
%do i=1 %to &n ;
%put %nrstr(%%)&sysmacroname ;
%put _user_ ;
%put ;
%end ;
%mend inner ;
%outer(n=2)
Log:
22 %outer(n=2)
%OUTER
OUTER I 1
OUTER N 2
%INNER
INNER I 1
INNER N 3
OUTER I 1
OUTER N 2
%INNER
INNER I 2
INNER N 3
OUTER I 1
OUTER N 2
%INNER
INNER I 3
INNER N 3
OUTER I 1
OUTER N 2
%OUTER
OUTER I 2
OUTER N 2
%INNER
INNER I 1
INNER N 3
OUTER I 2
OUTER N 2
%INNER
INNER I 2
INNER N 3
OUTER I 2
OUTER N 2
%INNER
INNER I 3
INNER N 3
OUTER I 2
OUTER N 2
With that, outer loops two times, so you get the expected 2*3=6 executions of INNER. And you can see in the log that the macro variables i and N in INNER are independent of the macro variables i and N in OUTER.
... View more