是否可以将带有宏触发器的字符串作为宏参数传递? 请参阅下面的示例代码:
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);
此代码已成功运行,但它尝试调用宏%abc和%def,这会导致警告。
如果我尝试将其用于引用以掩盖字符串,则会出现语法错误,如下所示:
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_, ~.
有没有办法在没有警告的情况下解决这个问题? 提前谢谢!
答案 0 :(得分:3)
试试这个:
%let string5='%abc%def%';
%macro test(string);
data _null_;
call execute('%test2('||%nrstr("&string.")||')');
run;
%mend;
%macro test2(string2);
data test3;
a=%nrquote(&string2.);
run;
%mend;
%test(&string5);
答案 1 :(得分:1)
宏中通常很简单,可以防止特殊字符。例如,您可以使用%superq()
函数来引用现有的宏变量值。
where name like %unquote(%str(%')%superq(parm1)%str(%'))
或者在数据步骤中使用symget()
函数来获取值,而无需扩展宏。
pattern = quote(symget('parm1'),"'");
但困难的部分是进行宏调用。您需要保护字符以使宏调用运行。您可以在宏调用中使用类似的功能。
一个有用的事情是指示用户将参数值作为带引号的字符串传递,然后在不需要时删除引号的宏代码。
%macro mymacro(parm1=);
%let parm1=%qsysfunc(dequote(&parm1));
...
%mend;
%mymacro(parm1='fred%')
或者您可以要求他们按名称传递值。
%macro mymacro(mvar=);
%local pattern ;
%let pattern=%superq(&mvar);
...
%mend ;
%let my_pattern=%qsysfunc(dequote('fred%'));
%mymacro(mvar=my_pattern)
答案 2 :(得分:0)
如果这已经按照您想要的方式工作,并且您只想抑制这一条警告消息,您可以考虑在运行相关代码段之前设置option nomerror;
,然后再将其重新设置。 / p>
答案 3 :(得分:0)
只需更新我选择的最终解决方案。我放弃了在不同宏之间传递宏参数的方法,而是将宏变量名称作为字符串传递。示例代码如下:
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');