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

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

View solution in original post

2 REPLIES 2
Tom
Super User Tom
Super User

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
pavelr
Obsidian | Level 7

Thanks, this will work for my case!

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 2 replies
  • 530 views
  • 2 likes
  • 2 in conversation