Hi guys,
Here is a weird thing I observed. Any help would be appreciated. In below code myvar is retained outside of macro call. But myvar2 is not retained(resolved). (I tried it on PC SAS no unix)
%macro test1();
data _null_;
call symput('myvar',"value resolved");
run;
%mend test1;
%test1;
%put &myvar;
%macro test2(param1);
data _null_;
call symput('myvar2',"value resolved");
run;
%mend test2;
%test2(parvalue);
%put &myvar2;
There's a funny rule that accounts for this funny behavior.
CALL SYMPUT never puts a macro variable into an empty symbol table. Instead, it puts the macro variable into the closest "non-empty" symbol table.
(Technically, there's no such thing as an empty symbol table ... the symbol table just doesn't exist at all. But the first paragraph is the way it's usually written up in the documentation.)
So when the first macro runs, there is no local symbol table. CALL SYMPUT creates a new macro variable and is forced store it in the global symbol table.
When the second macro runs, there is a local symbol table, since parameters on the %MACRO statement are always local. Therefore, when CALL SYMPUT creates a new macro variable, it gets stored in the local symbol table.
If you want your macro variables to be global, you can achieve that by switching to CALL SYMPUTX:
call symputx('myvar', "value will resolve this time", 'G');
The value of the third parameter (G) tells the software to use the global symbol table.
There's a funny rule that accounts for this funny behavior.
CALL SYMPUT never puts a macro variable into an empty symbol table. Instead, it puts the macro variable into the closest "non-empty" symbol table.
(Technically, there's no such thing as an empty symbol table ... the symbol table just doesn't exist at all. But the first paragraph is the way it's usually written up in the documentation.)
So when the first macro runs, there is no local symbol table. CALL SYMPUT creates a new macro variable and is forced store it in the global symbol table.
When the second macro runs, there is a local symbol table, since parameters on the %MACRO statement are always local. Therefore, when CALL SYMPUT creates a new macro variable, it gets stored in the local symbol table.
If you want your macro variables to be global, you can achieve that by switching to CALL SYMPUTX:
call symputx('myvar', "value will resolve this time", 'G');
The value of the third parameter (G) tells the software to use the global symbol table.
Thanks for your reply. I understand now what is going on. But it still sounds haphazard behavior on the part of SAS. I would expect better.
Thanks again.
This is neither good or bad. It's just a design decision. The variable could go to the most local table, or to the global one. Would that be better? Maybe. Maybe not. Which of the two would be better? Local? Global?
At least you have a choice here.
I appreciate your taking time to reply, but I don't agree with you. The same code should not behavie differently, just because you have a parameter in the macro definition. I think it is a bad design.
But anyways.. I now know what the problem is so corrected my code.
Thanks,
The only way achieve this would be to have to no scopes, and that all variables be global.
As soon as you have scopes, behaviours will change depending on where variables are defined.
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
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.