I'm trying to build a macro around the solution to this question
My reproducible example here doesn't do anything useful, it's just to highlight the syntax error I'm getting.
The line rc = mx.defineKey(&groups)
works in the first case, executing rc = mx.defineKey('grp1','grp2')
.
In the second case however, where I define &groups
differently but aiming at the same value, it fails with error:
NOTE: Line generated by the macro variable "GROUPS". 21
'grp1','grp2' _ 386 _ 200 76 MPRINT(TEST2): rc = mx.defineKey('grp1','grp2'); ERROR: DATA STEP Component Object failure. Aborted during the COMPILATION phase. ERROR 386-185: Expecting an arithmetic expression.ERROR 200-322: The symbol is not recognized and will be ignored.
ERROR 76-322: Syntax error, statement will be ignored.
Here are the working example followed by the non working one. I would like to:
groups
from grp_list
the appropriate way.Reproducible code:
data have;
input grp1 $ grp2 $ number;
datalines;
a c 3
b d 4
;
%macro test;
data want;
set have;
if _n_ = 1 then do;
declare hash mx();
%let groups = 'grp1','grp2';
%put rc = mx.defineKey(&groups);
%put rc = mx.defineKey('grp1','grp2');
rc = mx.defineKey(&groups);
rc = mx.definedata('number');
rc = mx.definedone();
end;
run;
%mend;
%test
%macro test2;
data want;
set have;
if _n_ = 1 then do;
declare hash mx();
%let grp_list = grp1 grp2;
%let groups = %str(%')%qsysfunc(tranwrd(&grp_list,%str( ),%str(%',%')))%str(%');
%put rc = mx.defineKey(&groups);
%put rc = mx.defineKey('grp1','grp2');
rc = mx.defineKey(&groups);
rc = mx.definedata('number');
rc = mx.definedone();
end;
run;
%mend;
%test2
You need to remove the macro quoting as it is adding invisible control characters that are messing up your hash definition. Change the relevant line to this:
rc = mx.defineKey(%unquote(&groups));
You might also consider defining a separate macro to quote each of your list items, and using double quotes rather than single quotes, e.g.
%macro quotelist(list);
%local i word;
%do %while(1);
%let i = %eval(&i + 1);
%let word = %scan(&list,&i,%str( ));
%if &word = %then %return;
%sysfunc(quote(&word)) /*De-indent to avoid adding extra spaces*/
%end;
%mend;
%put %sysfunc(translate(%quotelist(a b c),%str(,),%str( )));
This avoids the additional hassles associated with resolving macro variables inside single quotes.