Hi,
As a newbie, I just came across "macro variables". They are said to be local, but then I must misunderstand something. Below is an example that seems to generate a result that gives me the impression that a macro variable (in this case i) is not local within a macro, what do I miss?
%macro macro_B();
%put macro_B ... ;
%do i = 1 %to 5;
%put macro_B - looping [&=i];
%end;
%put macro_B - loop completed [&=i];
%mend;
%macro macro_A();
%put macro_A ... ;
%do i = 1 %to 3;
%put macro_A - looping [&=i];
%macro_B();
%end;
%put macro_A - loop completed [&=i];
%mend;
%macro_A();
Yields the following output
macro_A ...
macro_A - looping [I=1]
macro_B ...
macro_B - looping [I=1]
macro_B - looping [I=2]
macro_B - looping [I=3]
macro_B - looping [I=4]
macro_B - looping [I=5]
macro_B - loop completed [I=6]
macro_A - loop completed [I=7]
Happy for a quick explanation.
//C
That is a lovely test case you wrote up!
The point you are missing is that macro variables defined within a macro are not (necessarily) local by default. Thus if you want a macro variable to be local (which 99.9% of the time is the right design IMHO), you need to use the %LOCAL statement to declare them to be local.
If you add a %LOCAL statement to both macros, they will work as expected:
%macro macro_B();
%local i ;
%put macro_B ... ;
%do i = 1 %to 5;
%put macro_B - looping [&=i];
%end;
%put macro_B - loop completed [&=i];
%mend;
%macro macro_A();
%local i ;
%put macro_A ... ;
%do i = 1 %to 3;
%put macro_A - looping [&=i];
%macro_B()
%end;
%put macro_A - loop completed [&=i];
%mend;
%macro_A()
Without the %local statement, your macro B will not create a local macro variable named i. Instead the %do i=1 %to... statement in the macro B will use the macro variable i that belongs to the macro A. And that will then cause your macro A to stop looping prematurely. These kinds of scope collisions are a common problem if a macro does not declare the macro variables it creates to be %local.
I suspect you do not understand what SAS means by LOCAL.
When you define a macro variable as LOCAL is means that it only exists while it is running. If you call MACRO_B in the middle of running MACRO_A then MACRO_A is still running so the macro variable defined in MACRO_A still exists and can be used by MACRO_B.
When the same macro variable name exists in multiple scopes (GLOBAL, MACRO_A, MACRO_B, etc.) then references will use the most local (inner most) version.
If you define a macro variable as LOCAL that will prevent your macro from modifying some existing macro variable that happened to use the same name. So making a macro variable LOCAL will make your macro play nice with others. But it does not protect its macro variables from being modified by other macros it might call.
That is a lovely test case you wrote up!
The point you are missing is that macro variables defined within a macro are not (necessarily) local by default. Thus if you want a macro variable to be local (which 99.9% of the time is the right design IMHO), you need to use the %LOCAL statement to declare them to be local.
If you add a %LOCAL statement to both macros, they will work as expected:
%macro macro_B();
%local i ;
%put macro_B ... ;
%do i = 1 %to 5;
%put macro_B - looping [&=i];
%end;
%put macro_B - loop completed [&=i];
%mend;
%macro macro_A();
%local i ;
%put macro_A ... ;
%do i = 1 %to 3;
%put macro_A - looping [&=i];
%macro_B()
%end;
%put macro_A - loop completed [&=i];
%mend;
%macro_A()
Without the %local statement, your macro B will not create a local macro variable named i. Instead the %do i=1 %to... statement in the macro B will use the macro variable i that belongs to the macro A. And that will then cause your macro A to stop looping prematurely. These kinds of scope collisions are a common problem if a macro does not declare the macro variables it creates to be %local.
Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.