Testing for the existence of a global macro variable
[[last updated - 24 Mar 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.
The "declaring it %global" trick
This is not a recommended solution. 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
promotes that variable to be global
if it was not before. 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.
I use this technique a lot. It is quick and dirty but it does the job.
But maybe you need a better solution.
The %globexist macro
Using %globexist is the recommended solution. 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 it
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.
%symdel
At some stage you might want to delete all your global macro variables.
You can do this with the %symdel 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. 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.