3

is there a short way to make ALL macro variables created inside a macro global in scope?

ie:

%macro x;  
 %global _all_;  * ??? ;  
 %let x=1;  
 %let y=1;  
 %let z=1;  
%mend;
Allan Bowe
  • 12,306
  • 19
  • 75
  • 124
  • 3
    Do you really want to do this? You can clobber already existing global macro variables with your local ones. And you are asking for a way to do this implicitly! It is a recommended practice to declare %LOCAL (never %GLOBAL) all the variables you use in a macro. – Chang Chung Mar 12 '09 at 14:54
  • 3
    I absolutely agree with Chang Chung. You can easily cause problems for yourself or others if you make this a standard practice. If you absolutely have to do it, then try to ensure they are named using a prefix so that they won't be overwritten by accident. – Robert Penridge Apr 11 '12 at 17:18

3 Answers3

5

The only way I can think of to do this without having to declare each macro as global ahead of time and then do a %let statement is to use a macro in place of the %let statement.

In the code below, I create a macro called %mylet which has as its sole purpose the task of creating a global variable with the name and value I pass as arguments. I then use this macro in place of %let everywhere I want global variables defined.

eg.

%global myvar;
%let myvar=2;

would become...

%mylet(myvar,2);

/* Define a macro to declare variables as global */
%macro mylet(var,value);
  %global &var;
  %let &var.= &value ;
%mend;

/* Test macro */
%macro test;
 %mylet(myvar,2);
 %mylet(myvar2,12);
 %mylet(myvar3,'string');

/* see that they are global inside the macro */
title "Macro scope inside test macro";
proc sql;
    select *
       from dictionary.macros
       where name in('MYVAR','MYVAR2','MYVAR3');
quit;

%mend;
%test;

/* Check to see if they are still global outside the macro */
title "Macro scope outside test macro";
proc sql;
    select *
       from dictionary.macros
       where name in('MYVAR','MYVAR2','MYVAR3');
quit;
cmjohns
  • 4,465
  • 17
  • 21
  • Instead of querying the dictionary tables, you can simply do: %put _global_; or %put _local_; to see the list of global and local macro vars (and their values). You can also do %put _user_; to see only the user defined macro vars (and the values). – Chang Chung Mar 12 '09 at 15:01
  • 1
    Very true indeed. I chose to use the dictionary table in this case as I've found people are less familiar with these tables and I hoped it might give others new some things to explore. Also it let me easily isolate the three variables in the output no matter what other variables were defined. – cmjohns Mar 12 '09 at 18:56
4

If you create the macro variable within open code the macro variable will automatically be added to the global macro symbol table:

%let x=1;  
%let y=1;  
%let z=1; 

This would be before you create the larger macro:

%macro x;
  <code here>
%mend x;

Another alternative would be to create the variables using a data step:

data _null_;
    set LIB.DSET;
    x = 1;
    call symput('x',x);
run;
3

If you create macro variables within a data-step, and that data-step is inside a macro, the macro variables created will be, by default, local in scope to that macro.

Use

call symputx('macvar',macval,'g'); 

to create global macro variables.