SAS MACRO 引用问题:将带有宏触发器的字符串作为宏参数传递
SAS MACRO Quoting issue : passing string with macro trigger as macro parameter
是否可以将带有宏触发器的字符串作为宏参数传递?
请参阅下面的示例代码:
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_, ~.
有没有办法在没有警告的情况下解决这个问题?
提前致谢!
如果这已经按照你想要的方式工作,而你只是想抑制这条警告消息,你可以考虑在 运行 有问题的代码部分之前设置 option nomerror;
,然后设置之后又回来了。
在宏中通常很简单,可以防止特殊字符。例如,您可以使用 %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)
试试这个:
%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);
只是更新我选择的最终解决方案。我放弃了在不同宏之间传递宏参数的方式,而是将宏变量名作为字符串传递。示例代码如下:
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');
是否可以将带有宏触发器的字符串作为宏参数传递? 请参阅下面的示例代码:
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_, ~.
有没有办法在没有警告的情况下解决这个问题? 提前致谢!
如果这已经按照你想要的方式工作,而你只是想抑制这条警告消息,你可以考虑在 运行 有问题的代码部分之前设置 option nomerror;
,然后设置之后又回来了。
在宏中通常很简单,可以防止特殊字符。例如,您可以使用 %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)
试试这个:
%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);
只是更新我选择的最终解决方案。我放弃了在不同宏之间传递宏参数的方式,而是将宏变量名作为字符串传递。示例代码如下:
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');