BookmarkSubscribeRSS Feed
richard_hu2003
Fluorite | Level 6
56. The following SAS program is submitted:
%let a=cat;
%macro animal(a=frog);
%let a=bird;
%mend;
%animal(a=pig)
%put a is &a;
Which one of the following is written to the SAS log?
(A) a is &a
(B) a is cat
(C) a is pig
(D) a is bird

The answer is B. But why (D) is not correct? Thanks a lot!
16 REPLIES 16
SPR
Quartz | Level 8 SPR
Quartz | Level 8
Hello Richard_hu2003,

The question is related to global and local macrovariables relationship. In this case we have a global macro variable a with value 'cat', and inside the macro we have a local macrovariable a with value 'bird'. These are two different macro variables. Because macro does not change global macro variable its value remains unchanged and equals to 'cat'.

Sincerely,
SPR
richard_hu2003
Fluorite | Level 6
Got it! Thanks!
ArtC
Rhodochrosite | Level 12
Richard_hu2003,

SPR is absolutly correct but the reason that there is a local and global version of &A is more subtle. A slight change in the program will give D as the answer.
[pre]%let a=cat;
%macro animal(b=frog);
%let a=bird;
%mend;
%animal(b=pig)
%put a is &a;
[/pre]

now there is no version of &A on the local table, and cat is replaced by bird.

In your original version of the macro %ANIMAL it is the parameter (A=) that forces a &A to appear on the local table. A %LET inside the macro is not sufficient. I feel that this is an important, albeit fairly subtle, difference in behavior that gets folks into trouble.
richard_hu2003
Fluorite | Level 6
Very helpful!! Thanks, ArtC.
shidehrafigh
Fluorite | Level 6
Hi

I understand that first a global table with a= cat created and then a local table with a=frog created and in the last step it is updated to pig. But when resolving a macro variable (&a) doesn’t SAS first look into lical table and if it finds it it retrieves it from local (hence here pig) and if it cannot find it from local table it looks into global table?
LinusH
Tourmaline | Level 20
You are correct, but the question in the OP is based on resolving a macro variable in the global scope.
Data never sleeps
narravulap
Fluorite | Level 6

program: 


%let a=20;


%macro check;
%let a=50;
%put inside &a.;
%mend check;


%check;
%put outside &a.;

 

 

output :

 
 
inside 50
 
outside 50
 

 

 

Q: first i have defined variable a with %let , SAS will consider as global variable,

then same variable inside a macro ,SAS will consider as local variable.

 

But why it is printing both as 50, it should print inside 50 and outside 20 , right ?

 

can someone explain , why local variable is over writing global macro variable ?

 

 

@ArtC  @LinusH  @richard_hu2003  @shidehrafigh  @SPR 

Tom
Super User Tom
Super User

You have not defined any local macro variable.  So only the global macro variable exists.

Click on Spoiler below to see why.

Spoiler
There is no %LOCAL statement to define a local macro variable.
The macro does not define any parameters. Note that macro parameters are always LOCAL to the macro.
The %LET statement does not need to make a new macro variable since there is already a macro variable with that name.

 


@narravulap wrote:

program: 


%let a=20;


%macro check;
%let a=50;
%put inside &a.;
%mend check;


%check;
%put outside &a.;

 

 

output :

 
 
inside 50
 
outside 50
 

 

 

Q: first i have defined variable a with %let , SAS will consider as global variable,

then same variable inside a macro ,SAS will consider as local variable.

 

But why it is printing both as 50, it should print inside 50 and outside 20 , right ?

 

can someone explain , why local variable is over writing global macro variable ?

 

 

@ArtC  @LinusH  @richard_hu2003  @shidehrafigh  @SPR 


 

narravulap
Fluorite | Level 6
creating macro variable inside a macro , automatically consider as local right, ?
when i'm calling outside of a macro , why it is printing local macro variable?

%let statement inside a macro, creates a local macro variable
Tom
Super User Tom
Super User

@narravulap wrote:
creating macro variable inside a macro , automatically consider as local right, ?
when i'm calling outside of a macro , why it is printing local macro variable?

%let statement inside a macro, creates a local macro variable

The first statement is true. (Unless you use CALL SYMPUTX() with the third argument set to 'G'.)

The last statement is false.

Having a %LET statement inside of macro definition just means it does not execute until you call the macro.  The same as having a PROC PRINT statement inside of the macro definition.

 

When it does execute it only makes a NEW macro variable if the macro variable does not already exist.

narravulap
Fluorite | Level 6
Thanks for all your patients and reply, kindly elaborate below points , great help for me.


%let a=20;

%macro check;
%let a=50;
%put inside &a.;
%mend check;
%check;

%put outside &a.;

1. so, if there is a macro variable already defined as global, it will be global until we mentioned as local ?
2. macro parameters are by default, local variables ?
3.Macros will be stored in different two tables right ?, then it can store separately, a=20 as global because i have derived it with open code let statement and can store a=50 in local table can be referred only during that particular macro. ?
4. how this storing process works in SAS for macro variables ?

Thanks,
Pavan.
yabwon
Onyx | Level 15

Hi,

 

1) First, I highly recommend Maxim 1 

The following link provides documentation page with precise diagrams explaining how macro variables are created, populated, and resolved:

http://support.sas.com/documentation/cdl/en/mcrolref/67912/HTML/default/viewer.htm#p0g7wk5o8cji7ln16...

 

2) yes, macro parameters are local by default, run the following code and see the log:

%let mv = I an global!;

%macro test(mv=am I local?);
%put _local_;
%put ##################;
%put _user_;
%mend;

%test()

Log shows:

1    %let mv = I an global!;
2
3    %macro test(mv=am I local?);
4    %put _local_;
5    %put ##################;
6    %put _user_;
7    %mend;
8
9    %test()
TEST MV am I local?
##################
TEST MV am I local?
GLOBAL MV I an global!

You can see there local table (with TEST prefix for scope) has one variable and global table has one too (with GLOBAL prefix for scope)

 

3) and 4) If you run the following code:

%let mv = I an global!;

%macro testInside(mv=I am local even more!!);
proc print data=sashelp.vmacro;
run;
%mend;

%macro test(mv=am I local?);
%put _local_;
%put ##################;
%put _user_;

%testInside()

%mend;

%test()

you will see that all "available" scopes (in this case two "local" [one for test, second for testInside] and the global one) can be retrieve from one SAS view in sashelp library.

Order of observations goes from the most inner one to most global one. So even if we conceptually think about 3 macro variables tables, we can get all information from one place.

 

 

Bart

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

1. so, if there is a macro variable already defined as global, it will be global until we mentioned as local ?

No.  If you define a global macro variable it lives forever.  Or at least it used to before SAS added the %SYMDEL macro statement. 

 

But once you create a LOCAL macro variable with the same name you cannot see it.  Only the "inner most" or "closest" version of the macro variable can be used. 

 

The exceptions are that you can use CALL SYMPUTX() to modify global macro variables that are hidden (blocked) by a local macro variable.  And if you want to retrieve the value of a global (or other local scope) macro variable that is hidden you can use this macro:  https://github.com/sasutils/macros/blob/master/symget.sas

 

2. macro parameters are by default, local variables ?

Yes.  The parameters of a macro are local macro variables.

 

3.Macros will be stored in different two tables right ?, then it can store separately, a=20 as global because i have derived it with open code let statement and can store a=50 in local table can be referred only during that particular macro. ?

Only while the macro is executing. Once the macro finishes its local macro variables are gone.  Note that if your macro calls another macro that second macro can see and modify the first's local macro variables.  Just like you can see and modify global macro variables.  As long are they are not hidden.

 

4. how this storing process works in SAS for macro variables ?

No idea and it probably does not matter. 

 

If you print the SASHELP.VMACRO view (or query the DICTIONARY.MACROS table it references) you will see that each macro instance has a SCOPE.  The SCOPE is either GLOBAL (or AUTOMATIC which is just another name for GLOBAL macro variables the SAS created for you) or the name of the macro where they live.

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 16 replies
  • 7633 views
  • 10 likes
  • 11 in conversation