SAS Programming

DATA Step, Macro, Functions and more
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-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 812 views
  • 2 likes
  • 2 in conversation