Testing for the existence of a global macro variable

[last updated - 03 Sep 2008]

Introduction

In complex sas programs you maybe want to set up and use a macro variable but you want to be sure it is not already being used as you don't want to change its contents if that is the case. Note that you will not have a problem if you are working inside a macro that you wrote and you have declared your macro variable to be local. Instead, this applies to open code where a macro variable declaration will be treated as global or where a macro variable has been declared to be global using the %global statement within an existing macro.

%symexist

If you are using sas version 9 or later then you can test whether a global macro variable exists using the %symexist() macro function. It the macro variable exists then the value of "1" ("True") is returned and if not "0" ("False") is returned. Note that %symexist works for local macro variables as well.
 
1    %let r=rrrrr;
2    %put >> %symexist(r) >>>>;
>> 1 >>>>
3    %put >> %symexist(rnot) >>>>;
>> 0 >>>>

The "declaring it %global" trick

This is not a recommended solution but you might want to use it if you are using versions earlier than version 9 sas. I mention this on my macro tips page but I thought I would expand on it here. Let us say you want to do a bit of processing but it will be different if a global macro variable has been set. So you want to check on whether it exists or not. If you try to resolve its value and it has not been set up then you will get an error message and you want to avoid that. There is a quick and dirty way to do this and I will tell you about it before going on to more complex methods. That is - declare the macro variable as global like this - %global globvar; . Nearly every SAS programmer I know of makes the mistake in thinking that if you declare a macro variable as global then you will destroy the contents of that variable. This is not the case. Declaring a macro variable as global can be done multiple times without any warning or error message being issued. The contents of that variable are not affected. So all you have to do is to declare it global and test its contents. If it has a value then it must have been set up somewhere and so it must exist. If it has not been set up then it is set up now and its contents will be null. I used this technique a lot for version 8 sas. It is quick and dirty but it does the job. But maybe you need a better solution.

The %globexist macro

Using %globexist is another solution and is the one I use. It is a macro I wrote. Information about what macro variables have been set up can be found in the sashelp.vmacro view and the dictionary.macros SQL view so you can use these views to find out if the global macro variable already exists. There is a "scope" variable which will be set to "GLOBAL" for global macro variables (also macro variables set at a high level are regarded as global) and the name of the variable will be in uppercase and in the "name" field. Because getting to this information may not be convenient I wrote a function-style macro to return a list of global macro variables called globlist and one to check for the existence of all of one or more global macro variable called globexist. These macros do not contain any procedural or data step boundaries so they can be used in macro code in the form:
 
%if %globexist(globvar) %then .....

...and I assume the above is the most convenient form for finding out whether a global macro variable exists. No quick and dirty trick as in the previous section is used. The macro effectively reads the sashelp.vmacro view using SCL code called from a macro. Although it is opening, reading and then closing a SAS view, it is not using a data step to do this nor a procedural step so it can be used as a function-style macro.

Note the difference between %globexist and %symexist. %globexist only returns 1 for global macro variables whereas %symexist does so for local macro variables as well. The difference is illustrated below.
 
224  %let mvar1=xxxxxx;
225
226  %put >>>> outside macro then symexist for mvar1 = %symexist(mvar1) >>>>>> ;
>>>> outside macro then symexist for mvar1 = 1 >>>>>>
227  %put >>>> outside macro then symexist for mvar2 = %symexist(mvar2) >>>>>> ;
>>>> outside macro then symexist for mvar2 = 0 >>>>>>
228  %put >>>> outside macro then globexist for mvar1 = %globexist(mvar1) >>>>> ;
>>>> outside macro then globexist for mvar1 = 1 >>>>>
229  %put >>>> outside macro then globexist for mvar2 = %globexist(mvar2) >>>>> ;
>>>> outside macro then globexist for mvar2 = 0 >>>>>
230
231  %macro test;
232    %let mvar2=yyyyyy;
233    %put >>>> inside macro then symexist for mvar1 = %symexist(mvar1) >>>>>> ;
234    %put >>>> inside macro then symexist for mvar2 = %symexist(mvar2) >>>>>> ;
235    %put _user_;
236    %put >>>> inside macro then globexist for mvar1 = %globexist(mvar1) >>>>> ;
237    %put >>>> inside macro then globexist for mvar2 = %globexist(mvar2) >>>>> ;
238    %symdel mvar2;
239    %put _user_;
240  %mend;
241
242  %test;
>>>> inside macro then symexist for mvar1 = 1 >>>>>>
>>>> inside macro then symexist for mvar2 = 1 >>>>>>
TEST MVAR2 yyyyyy
GLOBAL _NOMATCH_ MVAR2
GLOBAL MVAR1 xxxxxx
>>>> inside macro then globexist for mvar1 = 1 >>>>>
>>>> inside macro then globexist for mvar2 = 0 >>>>>
WARNING: Attempt to delete macro variable MVAR2 failed. Variable not found.
TEST MVAR2 yyyyyy
GLOBAL _NOMATCH_ MVAR2
GLOBAL MVAR1 xxxxxx
243
244  %put >>>> outside macro then symexist for mvar1 = %symexist(mvar1) >>>>>> ;
>>>> outside macro then symexist for mvar1 = 1 >>>>>>
245  %put >>>> outside macro then symexist for mvar2 = %symexist(mvar2) >>>>>> ;
>>>> outside macro then symexist for mvar2 = 0 >>>>>>
246  %put >>>> outside macro then globexist for mvar1 = %globexist(mvar1) >>>>> ;
>>>> outside macro then globexist for mvar1 = 1 >>>>>
247  %put >>>> outside macro then globexist for mvar2 = %globexist(mvar2) >>>>> ;
>>>> outside macro then globexist for mvar2 = 0 >>>>>
 

Note that in the above log output then "GLOBAL _NOMATCH_ MVAR2" does not mean that MVAR2 is a global macro variable. It means that _NOMATCH_ is a global macro variable and has been assigned the value "MVAR2".

%symdel

At some stage you might want to delete all your global macro variables. You can do this with the %symdel macro command and if you combine it with the %globlist macro then it becomes a very simple matter. Look at the log below.
 
1 %let test1=1;
2 %let test2=2;
3 %put _global_;
GLOBAL TEST1 1
GLOBAL TEST2 2
4 %symdel %globlist;
5 %let test3=3;
6 %put _global_;
GLOBAL TEST3 3

You will see in the log that I set up two (effectively) global macro variables test1 and test2 and then displayed them using the %put _global_ command. (Note that if these macro variables exist in open code then they are treated like global macro variables and recognized by SAS macro code as such. There is no need to declare them as global). I then use %symdel %globlist to delete these global macro variables. Then I create a third global macro variable called test3. So when I display these global macro variables using the %put _global_ statement you will see that only test3 is left.

Note that %symdel only acts on global macro variables and not local macro variables. You will see a warning in the log in the previous section where an attempt to use it to delete MVAR2 failed. This is a bit strange since %symexist also acts on local macro variables and you might think that %symdel had the same scope as %symexist -- but it has not. Also you should note that (for some strange reason) if you use %symdel in the form:
 
%symdel &var;

...inside a macro then you might get a syntax error, but it will work outside a macro in that form without a problem. This is a known bug and there is a fix for it which you can read about here.
 


 
 

Go back to the home page.

E-mail the macro and web site author.