2017-04-20 77 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');