2017-08-22 58 views
2

有沒有一種方法可以打印由宏生成的SAS代碼而不執行它?生成SAS宏代碼而不執行它

謝謝

+1

簡短的回答你可能不想聽到:使用'%put'語句 – user2877959

+0

@ user2877959你的建議將爲小宏做竅門,但不適用於複雜和長期的宏。感謝您的建議 – Arjjuna

+1

因此,爲什麼我預測您不會喜歡答案 – user2877959

回答

1

不,一般不會。宏是一個生成SAS代碼的程序,因此要知道它將生成的代碼的唯一方法就是運行它。在一些非常簡單的情況下,您可能能夠解析宏並確定將生成哪些SAS代碼,但對於任何更復雜的情況,您必須重新實現一個程序來讀取,解析並執行此宏上班。另見the Halting Problem

+0

所以我理解的是,如果這樣的設施存在,它肯定不適用於所有的宏。 – Arjjuna

+1

正確。只要考慮一下宏可能做什麼處理 - 它可能會連接到一個實時生產數據庫,然後爲在過去30分鐘內收到的每個訂單生成一些代碼,並附加一些額外的代碼以實現特定值的訂單......任何一般宏分析器能夠預測宏將爲給定運行處理多少個命令? –

+1

我認爲這個答案在某種程度上誤解了想要的東西。是的,您可能必須運行_macro_,但運行宏而不運行它生成的SAS代碼似乎符合問題的目標。我並不認爲在某些情況下,目標是不可能的,但似乎這個問題可能不那麼強烈。 – Joe

2

有幾種方法可以達到您想要的效果,至少在某些時候可以工作。

您可以設置options obs=0;,然後運行宏(開啓MPRINT)。這將運行宏,但不會處理任何數據行。這將適用於許多宏;但它會覆蓋數據集,所以如果你關心被保存的任何內容,這是不安全的。

%macro do_something; 
    data test; 
    set sashelp.class; 
    run; 
%mend do_something; 

options mprint; 
options obs=0; 

%do_something; 

WORK.TEST被覆蓋,注意,但沒有觀察處理。

現在,如果你正在談論一個存儲的編譯宏(這看起來是最有用的場景,不是?),那麼它取決於它是如何存儲的。如果它與/source交換機一起存儲,那麼您可以使用%COPY獲得源代碼。

libname sasdir "e:\temp"; 
options mstored sasmstore=sasdir; 

%macro do_something/store source; 
    data test; 
    set sashelp.class; 
    run; 
%mend do_something; 

%copy do_something/source; 

它要求它已經編譯了source標誌,但是。如果不是,那麼源代碼在運行代碼之前是不可恢復的。

2

另一種方法,如果您的宏主要是數據步和PROC SQL,是使用run cancel;proc sql noexec;選項,例如如下:

%macro example(somelogic=1,execute=NO); 

    %local cancel noexec; 
    %if &execute=NO %then %do; 
    %let cancel=cancel; 
    %let noexec=noexec; 
    %end; 

    data some_ds; 
    set some_other_ds; 
    %if &somelogic %then %do; 
    this=that; 
    %end; 
    run &cancel; 

    proc sql &noexec; 
    create table maybe as 
    select * from have; 

%mend; 

這樣你的代碼將被生成/語法檢查但沒有執行。

當然 - 這是一個'小心處理'的方法,因爲仍然有很多東西在宏觀環境中仍然可以改變。 @Chris Long是正確的 - 沒有執行它的生成SAS代碼沒有可靠的方法(因爲生成的實際代碼通常取決於早期執行的結果)。

0

您可以嘗試使用PROC STREAM。 讓我們定義一個簡單的宏

%macro mymacro; 
proc print data=sashelp.class; run; 
%mend; 

做一個fileref包含生成的代碼

filename mycode temp; 

現在你可以使用PROC STREAM到宏調用轉換爲文本。

proc stream outfile=mycode; BEGIN 
%mymacro 
;;;; 

它應該適用於任何不需要根據它生成的代碼的結果作出決定的宏。