BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
anu1999
Obsidian | Level 7

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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 ;

 

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

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 ;

 

anu1999
Obsidian | Level 7

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.

Tom
Super User Tom
Super User

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 ;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 2218 views
  • 1 like
  • 2 in conversation