Hi all,
I'm trying to set something up within a DATA _NULL_ step to test whether or not a global macro variable exists, and then if it doesn't to create it and assign a value.
However, it looks like maybe my %GLOBAL statement is getting resolved before the DATA step finishes executing?
Here's some example code I came up with to demonstrate:
data _null_;
put "TEST 1" ;
if symexist("MacVar1") then do;
put "TEST INSIDE DO LOOP 1" ;
end;
else do;
put "TEST INSIDE DO LOOP 2" ;
put "MacVar1 macro variable does not yet exist" ;
%global MacVar1;
end;
put "TEST 2" ;
if "&MacVar1"="" then call symputx ('MacVar1','0') ;
put "TEST 3" ;
run;
data _null_;
put "TEST 4" ;
if symexist("MacVar2") then do;
put "TEST INSIDE DO LOOP 3" ;
end;
else do;
put "TEST INSIDE DO LOOP 4" ;
put "MacVar2 macro variable does not yet exist" ;
end;
put "TEST 5" ;
if "&MacVar2"="" then call symputx ('MacVar2','0') ;
put "TEST 6" ;
run;
The only functional difference between those two DATA steps is the "%GLOBAL" statement within the ELSE DO. When I run it, I get the following in the log:
TEST 1
TEST INSIDE DO LOOP 1
TEST 2
TEST 3
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
WARNING: Apparent symbolic reference MACVAR2 not resolved.
TEST 4
TEST INSIDE DO LOOP 4
MacVar2 macro variable does not yet exist
TEST 5
TEST 6
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
In other words, in the first DATA step (the one with the %GLOBAL statement), it detects the existence of MacVar1, even though the %GLOBAL statement is after the SYMEXIST.
So, can anyone help me figure out the right way to set this up? Basically, I would like to check whether or not MacVar1 exists. If it doesn't exist, then I'd like to create it as a global macro variable. Either way, does or does not exist, I then want to check whether or not it has a value, and if it doesn't then assign a value to it.
As you have seen, a DATA step cannot use IF/THEN to determine whether to execute a %GLOBAL statement. The %GLOBAL statement is not part of the DATA step, and executes immediately (before SAS finishes interpreting the meaning of the DATA step statements). While there are other approaches to solving your original problem, the simplest answer to your question is to change the %GLOBAL statement to this:
call execute('%global macvar1;');
Good luck.
use SYMPUTX with global option in place of %GLOBAL. You are correct %GLOBAL has already happened before data step starts.
As you have seen, a DATA step cannot use IF/THEN to determine whether to execute a %GLOBAL statement. The %GLOBAL statement is not part of the DATA step, and executes immediately (before SAS finishes interpreting the meaning of the DATA step statements). While there are other approaches to solving your original problem, the simplest answer to your question is to change the %GLOBAL statement to this:
call execute('%global macvar1;');
Good luck.
On second thought, CALL EXECUTE will solve the first problem, but not the second. It will create &MACVAR1 only if needed. But it won't create it in time for the final DATA step IF/THEN (TEST 3) to find it.
It would be reasonable to just move the %GLOBAL statement to before the DATA step begins. It won't do anything if &MACVAR1 already exists. Then the DATA step can always resolve &MACVAR1
Thanks! That definitely makes sense. I know the %GLOBAL wasn't actually part of the DATA step, so I don't know why I was thinking about it that way before. :smileyshocked:
I ended up going with:
data _null_;
put "TEST 1" ;
if ^symexist("MacVar1") then do;
put "TEST INSIDE DO LOOP 2" ;
put "MacVar1 macro variable does not yet exist" ;
call execute('%global MacVar1;');
end;
put "TEST 2" ;
run;
data _null_;
if "&MacVar1"="" then call symputx ('MacVar1','0') ;
put "TEST 3" ;
run;
That seems to give me what I'm looking for.
Thanks again!
Maybe you are making this more complicated than you need
Is the action any different if MACVAR1 does or does not exit. In other words do you always want it GLOBAL and to give it a new value.
Why not just use SYMPUTX('MACVAR1',0,'GLOBAL'); ?
Once you start examining alternatives (rather than solving for the original error message), you might get rid of the DATA step entirely:
%global macvar1;
%if %length(&macvar1)=0 %then %let macvar1=0;
There are possible complications if your statements appear inside a macro that might have a local macro variable named macvar1.
Good luck.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.