SAS MACRO引用问题:将带有宏触发器的字符串作为宏参数传递

时间:2017-04-20 04:07:08

标签: macros sas quoting

是否可以将带有宏触发器的字符串作为宏参数传递? 请参阅下面的示例代码:

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_, ~.  

有没有办法在没有警告的情况下解决这个问题? 提前谢谢!

4 个答案:

答案 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');