2013-10-31 226 views
1

我想知道如何從變量設置宏名稱。SAS - 從變量創建宏名稱

像這樣:

%Macro test(name); 
     ... 
     %Macro new_&name; 
     ... 
     %Mend; 
     ... 
    %Mend test 

或者,如果這是不可能的:

%macro one(name); 
     %let mname=&name; 
    %mend one; 

    %macro two_&name; 
     ... 
    %mend; 

任何想法?非常感謝。

+0

我想你的建議什麼工作?你試過了嗎?但是,你爲什麼要這樣做?我無法看到應用程序。 – ESmith5988

+1

您好ESmith,當然我測試了我的建議,但都無法正常工作。我有一個問題,它使用非常深的嵌套程序片段。爲了讓它們更具可讀性和可用性,我必須使用可以設置可編程宏而非單手設置宏名的宏來生成宏。希望這可以讓問題更清楚:) –

回答

1

首先我想到的是使用一個臨時的fileref來構建你的宏。然後包含該fileref。

我覺得這樣是你在找什麼:

%macro test(x,file); 
data _null_; 
file &file; 
format outStr $2000.; 

    outStr = ('%macro test_' || strip("&x") || "();"); 
    put outStr; 
    put '%put hello world;'; 
    outStr = '%put Passed in value is x:' || "&x and file: &file;"; 
    put outStr; 
    put "proc means data=sashelp.class(obs=&x) mean; var age; run;"; 
    put '%mend;'; 
run; 
%include &file; 
%mend; 

filename tempfile temp; 
%test(2,tempfile); 
%test_2; 

filename tempfile clear; 
+0

這種方法的積極的一點是你可以很容易地讓fileref成爲一個永久文件,這樣可以讓你看到生成的代碼,這對於調試或者以後的重用很有用。 – DomPazz

1

是你可以做這樣的事情:

%macro macroFunc(); 
    %put hi there; 
%mend; 
%macro macroCall(macroName); 
    %&macroName.(); 
%mend; 
%mcr2(macroFunc); 

但我在什麼情況下,這是有道理真的很好奇。似乎很快就會導致編碼混亂。

+0

我在開發需要「插件」的系統時經常使用它。給定一個規定的簽名,創建N個宏來做事情(通常適合不同類型的計量經濟模型)。然後有一個數據驅動系統來適應模型。它類似於OO語言的界面。 – DomPazz

+0

Hi Shorack,謝謝你的幫助。對於我來說,目前還不清楚你的程序如何解決我的問題。我從你的程序中瞭解到的是: 1)用名稱macrofunc定義一個宏。除了將消息寫入日誌,這裏沒有任何事情要做。 2)用名稱macroCall定義一個宏。這裏提交了一個參數(macroname)。參數macroname然後連接到大括號。所以這個大括號應該替換爲我想用於後面宏的名字。例如。 %macroName.new;或者像我的例子%new_&macroName; 3)調用一個尚未定義的宏? 希望你能幫忙。 –

+0

@DomPazz如果你經常使用這個,你會如此善良並提交你的解決方案來解決這個問題。非常感謝 –

1

我從來不知道你不能在%MACRO語句中使用變量......但似乎是這種情況。正如它在SAS文檔(http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#macro-stmt.htm)中所述,「不能使用文本表達式在%MACRO語句中生成宏名稱。」

我的下一個想法是,你可能能夠創建%MACRO語句作爲變量,但我無法找到一種方法來屏蔽%MACRO創建變量。

我終於想出了一個解決方法,但它可能不是最好的方法來做到這一點(它可能不適用於你想要做的)。我發現我可以在數據步驟中編譯宏語句。不幸的是,當整個宏代碼(從%MACRO到%MEND語句)保存在變量中時,我只能從變量運行宏。請參閱下面的代碼。

%MACRO test(name); 
data test; 
    *COMPILE MACRO STATEMENT; 
    pct=%nrstr('%'); 
    name="new_&name"; 
    beginning=pct||'MACRO '||strip(name)||'();'; 

    *CODE TO BE INSIDE MACRO; 
    /*Note: SAS will encounter errors if you try to assign text containing macro 
     functions (e.g., %PUT, %IF, etc.) to a variable. To get around this, you must 
     put hide the % in the following syntax, %nrstr('%'), and concatenate/join the 
     syntax with the rest of the string */ 
    code=pct||'PUT HELLO!;'; 

    *COMPILE MEND STATEMENT; 
    end=pct||'MEND;'; 

    call symput('MacroStatement',beginning||code||end); *Output var containing macro; 
    call symput('Execute',pct||strip(name)||';'); *Output var containing statement to run macro; 
    output; 
run; 

&MacroStatement 
&Execute 

%MEND; 
%test(name1); 
1
options mprint mlogic symbolgen nospool; 

%let definition=abc; 

%let mdef=macro &definition.; 

%&mdef.; 
    %put TEST; 
%mend; 


%abc;