- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, this will work for my case!