BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
andreas_zaras
Pyrite | Level 9

Hello,

I have the following macro:

%macro varscope;

data _null_;

set xxx.yyy end=final;

call symputx('localtype'||left(_n_), Customer_Type);

if final then call symputx('localn',_n_);

run;

%put _user_;

%mend varscope;

%varscope;

In the log i see that the macro variables are stored in the global symbol table. Why is that? According to the theory if a macro variable is created withing a specific macro like the varscope it should be placed in a local symbol table. Why in this case the macro variables are storeed in the global symbol table?

Thanks in advance,

Andreas

1 ACCEPTED SOLUTION

Accepted Solutions
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Let me try that again.  Default is global scope for macro variables.  If you look at the help documentation:

http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002295697.htm

You will see there is an optional parameter - for symbol table which will allow you to store locally or globally.

View solution in original post

6 REPLIES 6
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Let me try that again.  Default is global scope for macro variables.  If you look at the help documentation:

http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002295697.htm

You will see there is an optional parameter - for symbol table which will allow you to store locally or globally.

andreas_zaras
Pyrite | Level 9

Thanks for your answer. I am reading the course notes of the course SAS Macro language 1 and it says the following:

Local macro variables can be created by the following within a macro definition:

%let statement

data step symputx routine

proc sql select statement into clause

% local statement

According to the above since in my example i create the macro variable within a macro program using the data step symputx it should be included in a local symbol table.

Am i thinking something worng?

Thnaks,

Andreas

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Well, I don't know about that course or its notes.

The %local is correct.

The call symputx is also correct, but you have to remember that the default operation for that function, i.e. the value for table if you don't specify otherwise, will be G for global give or take some rules on the SYMPUT function.

As for the %let and select into, I don't know off the top of my head, would need to check.

TBH I don't think many actually care about scope as long as they can access it when wanted.

Peter_C
Rhodochrosite | Level 12

call symput() places values in the "nearest"  environment where that name is found (locals are nested within the global environment)

When the name is not found, call symput() creates a macro variable in the nearest environment that exists.

A %local in a macro ensures it has it's own environment, and macro parameters will establish an environment for the macro too.

A macro with no local environment would create macro variables in the "calling environment" - when macros are nested, that might not mean creating in global.

 

call symputX creates as directed by the 3rd parameter (F, G or L) G and L are as you would expect. For F I have clipped the online doc below

F

specifies that if the macro variable exists in any symbol table, CALL SYMPUTX uses the version in the most local symbol table in which it exists. If the macro variable does not exist, CALL SYMPUTX stores the variable in the most local symbol table.

Note: If you omit symbol-table or if symbol-table is blank, CALL SYMPUTX stores the macro variable in the same symbol table as does the CALL SYMPUT routine.

jakarman
Barite | Level 11

Interesting and a possible pitfall. But it is documented. SAS(R) 9.4 Macro Language: Reference (Symput)  : SYMPUT puts the macro variable in the most local nonempty symbol table.
Your macro has not defined any local variables, the local sysmbol table is empty it will move to the next non-empty one.  That is the global table.

Tested this with:

Data test;
   Customer_Type= "someone" ; 
   output;
run;

%macro varscope;
    %let scopetest = macro let;
    data _null_;
        set work.test end=final;
        call symputx('localtype'||left(_n_), Customer_Type);
        if final then call symputx('localn', _n_);
    run;
    %put _user_;
%mend varscope;

Without the scopetest it is creating you macrodefs as global. Adding just the local scoptest with that let is causing a non empty local table.

Run this in a clean SAS session and all you macro-vars are local scope.

Do not forget to reset you SAS session or undefine (symdel) the macro-vars as symput will use the visible existing defnitions.
That was an other maybe cause. Running the datastep out of the macro causing them global. The scope will not switch.

---->-- ja karman --<-----
Tom
Super User Tom
Super User

This is documented behavior.  It is because your macro did not create a local environment, so SYMPUT() stored the the new variable in the first environment that if found. Notice that if you nest this macro call inside of a another executing macro that does define a scope then the variable will be created there.  It also makes a difference if the variable already exists or not.  Try this little example.

%macro varscope;

  data _null_;

    call symput('test','VARSCOPE');

  run;

  %put _user_;

%mend varscope;

%macro outer;

  %local outer ;

  %varscope;

%mend;

%symdel test ;

%outer;

%varscope;

%outer;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 6 replies
  • 3376 views
  • 11 likes
  • 5 in conversation