2017-04-20 76 views
3

这是可能将具有宏触发器的字符串作为宏参数传递吗? 请参阅下面的示例代码:SAS MACRO引用问题:将具有宏触发器的字符串作为宏参数传递

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

你究竟在做什么?这可能是一个更简单的方法。 – user667489

+0

我试图通过类似的模式作为参数,其中包含%。我在这里做的只是一个例子。 –

+0

当通过CALL EXECUTE调用宏时,使用'%nrstr()'非常有用,但我不确定这对您的问题是否有影响。 '调用执行(猫'('%nrstr(%test2)(',symget('string'),')');' – Tom

回答

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); 
+0

它的工作原理!非常感谢。令我困扰的是,%nrstr只能接受常量文本并且不会解析任何宏,但如果常量文本是双引号的,则不是这种情况。 –

+0

更正,在编译期间将其掩盖,但让它在执行阶段解决,这将解决问题。 –

0

如果这已经按照你想要的方式工作,并且你只想压制这个警告信息,那么在运行代码段之前,然后再将其设置回来之前,可以考虑设置option nomerror;

+0

谢谢,但我不会更喜欢,因为我不能预料其他警告 –

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) 
+0

谢谢。 –

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