There a dataset. I need to call a macro for every value of a certain column. This column has some values with an "elision" French symbol which is like an unmatched single quote. How can I pass this value to a macro in a loop using call execute?
Here is an example:
/* Initial dataset. Need to loop over its values. In reality this dataset has many rows. */
data test;
mvar="L'université";
run;
/* Macro to call for every row in the dataset. */
%macro test(obj=);
/* Some code...*/
%put &obj.;
%mend;
/* Loop to call macro for every row in the dataset. */
data _null_ ;
set test ;
str=catt('%test(obj=%nrstr(',mvar,'));');
call execute(str);
run;
This code results in errors:
ERROR: Expected close parenthesis after macro function invocation not found.
ERROR: Macro parameter contains syntax error.
Thanks for any help.
The easiest way is to code the macro to expect (or at least allow) the parameter to be passed with actual quotes.
%macro test(obj=);
%let obj=%sysfunc(quote(%qsysfunc(dequote(&obj)),%str(%')));
proc print data=sashelp.class;
where name = &obj ;
run;
%mend;
Then use the QUOTE() function in your data step to add the quotes to the generated macro call.
data _null_ ;
set test ;
call execute(cats('%nrstr(%test)(obj=',quote(trim(mvar),"'"),')'));
run;
Example:
696 options mprint; 697 data _null_ ; 698 do mvar='Alfred','Alice'; 699 call execute(cats('%nrstr(%test)(obj=',quote(trim(mvar),"'"),')')); 700 end; 701 run; NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds NOTE: CALL EXECUTE generated line. 1 + %test(obj='Alfred') MPRINT(TEST): proc print data=sashelp.class; MPRINT(TEST): where name = 'Alfred' ; MPRINT(TEST): run; NOTE: There were 1 observations read from the data set SASHELP.CLASS. WHERE name='Alfred'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 2 + %test(obj='Alice') MPRINT(TEST): proc print data=sashelp.class; MPRINT(TEST): where name = 'Alice' ; MPRINT(TEST): run; NOTE: There were 1 observations read from the data set SASHELP.CLASS. WHERE name='Alice'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds
The easiest way is to code the macro to expect (or at least allow) the parameter to be passed with actual quotes.
%macro test(obj=);
%let obj=%sysfunc(quote(%qsysfunc(dequote(&obj)),%str(%')));
proc print data=sashelp.class;
where name = &obj ;
run;
%mend;
Then use the QUOTE() function in your data step to add the quotes to the generated macro call.
data _null_ ;
set test ;
call execute(cats('%nrstr(%test)(obj=',quote(trim(mvar),"'"),')'));
run;
Example:
696 options mprint; 697 data _null_ ; 698 do mvar='Alfred','Alice'; 699 call execute(cats('%nrstr(%test)(obj=',quote(trim(mvar),"'"),')')); 700 end; 701 run; NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds NOTE: CALL EXECUTE generated line. 1 + %test(obj='Alfred') MPRINT(TEST): proc print data=sashelp.class; MPRINT(TEST): where name = 'Alfred' ; MPRINT(TEST): run; NOTE: There were 1 observations read from the data set SASHELP.CLASS. WHERE name='Alfred'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 2 + %test(obj='Alice') MPRINT(TEST): proc print data=sashelp.class; MPRINT(TEST): where name = 'Alice' ; MPRINT(TEST): run; NOTE: There were 1 observations read from the data set SASHELP.CLASS. WHERE name='Alice'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds
Thanks, this will work for my case!
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.