Hi All,
I am struggling with this issue where macro variables are not getting resolved when i use call execute function in sas.
/* Data set */
data files ;
job = 1 ;
type = 'A' ;
group='ONE' ;
date='01jan2017'd ;
run ;
/*macro */
%macro checkit(xjob=, xtype=, xgroup=) ;
%let xdate=;
proc sql;
select date into :xdate
from files
where job = &xjob.
and type = &xtype.
and group = &xgroup.;
quit;
%put xdate = &xdate. ;
%mend checkit ;
data _null_ ;
set files ;
call execute("%checkit(xjob = 1, xtype = 'A', xgroup='ONE')") ;
run ;
However If I execute macro like this (see below) it resolves xdate correctly.
%checkit(xjob = 1, xtype = 'A', xgroup='ONE') ;
Any idea why its happening and how can I fix it?
Thanks in advance.
Don't use double quotes, otherwise the macro will be executed and the result put into the string that you are trying to push onto the command stack.
But even then you might have trouble since the macro will still execute when CALL EXECUTE tries to push the macro call onto the stack. This means that the macro logic is executing BEFORE any of the code that it generates. Hence the macro variable the code is going to generate doesn't exist yet.
One way to avoid this is to wrap the macro call inside of %NRSTR() macro function. Then it will get pushed onto the stack as-is not execute until it is pulled from that stack after the data step ends.
data _null_ ;
set files ;
call execute(cats(
'%nrstr(%%checkit)'
,'(xjob =',job
,',xtype =',quote(type)
,',xgroup=',quote(group)
,')'
));
run ;
Don't use double quotes, otherwise the macro will be executed and the result put into the string that you are trying to push onto the command stack.
But even then you might have trouble since the macro will still execute when CALL EXECUTE tries to push the macro call onto the stack. This means that the macro logic is executing BEFORE any of the code that it generates. Hence the macro variable the code is going to generate doesn't exist yet.
One way to avoid this is to wrap the macro call inside of %NRSTR() macro function. Then it will get pushed onto the stack as-is not execute until it is pulled from that stack after the data step ends.
data _null_ ;
set files ;
call execute(cats(
'%nrstr(%%checkit)'
,'(xjob =',job
,',xtype =',quote(type)
,',xgroup=',quote(group)
,')'
));
run ;
Hi Tom,
Thank you so much!!
This works but do you mind explaining how using %NSTR solved that issue and also I couldn't understand why you used %% (double percent) before checkit.
Thanks again!!
Aprreciate your help.
First look at the manual pages for the %STR() and %NRSTR() macro functions to understand why you need to double the %.
The issue is timing. You can see it in action by looking at the lines in the SAS log with plus signs (+) in front of them showing the code that CALL EXECUTE generates. When you use the %NRSTR() you will see that the line has the macro call. Without that they will have the lines of code that the macro generates.
Try running this test and check the log carefully and see if you can figure out what happened.
%macro x(value);
%let x=&value;
data x; x=&value; run;
%mend x;
options mprint;
%let x=0;
%put Before DATA _NULL_ X=&x ;
data _null_;
x=symget('x'); put 'BEFORE (1) ' x=;
call execute("%x(1)");
x=symget('x'); put 'BEFORE (2) ' x=;
call execute('%x(2)');
x=symget('x'); put 'BEFORE (3) ' x=;
call execute('%nrstr(%%x)(3)');
x=symget('x'); put 'AFTER (3) ' x=;
run;
%put After DATA _NULL_ X=&x ;
Yes, Just read it here: http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a001061290.htm
It makes sense.
Thanks 🙂
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.