SAS MACRO Quote issue: Passing a string using a macro as a macro parameter
Is it possible to pass a string with a macro trigger as a macro parameter? See sample code below:
options mprint;
%let string5='%abc%def%';
%macro test(string);
data _null_;
call execute('%test2('||&string.||')');
run;
%mend;
%macro test2(string2);
data test3;
a=%str(%')&string2.%str(%');
run;
%mend;
%test(&string5);
This code worked successfully, but it tried to call the% abc and% def macros, which resulted in warnings.
If I tried to put it in a quote to mask the string, it gave a syntax error like below:
options mprint;
%let string5='%abc%def%';
%macro test(string);
data _null_;
call execute('%test2('||%superQ(string)||')');
run;
%mend;
%macro test2(string2);
data test3;
a=%str(%')&string2.%str(%');
run;
%mend;
%test(&string5);
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, a missing value, arrayname, (, +, -, INPUT, NOT, PUT, ^, _NEW_, ~.
Is there a way to fix this without warnings? Thanks in advance!
source to share
Usually macros are usually fairly simple to protect against special characters. For example, you can use a function %superq()
to specify an existing value for macro variables.
where name like %unquote(%str(%')%superq(parm1)%str(%'))
Or use a function symget()
in a data step to get the value without having to expand the macro at all.
pattern = quote(symget('parm1'),"'");
But the tricky part is calling the macro. You need to protect symbols in order to trigger the macro call. You can use similar functions in a macro call.
One useful task is to instruct users to pass the parameter value as a quoted string, and then the macro code you can remove the quotes when they are not needed.
%macro mymacro(parm1=);
%let parm1=%qsysfunc(dequote(&parm1));
...
%mend;
%mymacro(parm1='fred%')
Or you can ask them to pass the value by name.
%macro mymacro(mvar=);
%local pattern ;
%let pattern=%superq(&mvar);
...
%mend ;
%let my_pattern=%qsysfunc(dequote('fred%'));
%mymacro(mvar=my_pattern)
source to share
Just update to the final solution I choose. I gave up on the way of passing macro parameters between different macros, instead I passed the name of the macro variable as a string. Code examples are given below:
options mprint;
%let string5='%abc%def%';
%macro test(string);
data _null_;
call execute('%test2('||&string.||')');
run;
%mend;
%macro test2(string2);
data test3;
a=&&&string2.;
run;
%mend;
%test('string5');
source to share