2013-02-12 116 views
0

下面是宏代碼.....如何爲sas數據集中的每個觀測值執行一個宏?

libname myfmt "&FBRMrootPath./Formats"; 
%macro CreateFormat(DSN,Label,Start,fmtname,type); 
options mprint mlogic symbolgen; 
%If &type='n' %then %do; 
    proc sort data=&DSN out=Out; by &Label; 
     Run; 
    Data ctrl; 
     set Out(rename=(&Label=label &Start=start)) end=last; 
     retain fmtname &fmtname type &type; 
     output; 
    If last then do; 
     hlo='O'; 
     label='*ERROR'; 
     output; 
    End; 
Run; 
%End; 
%Else %do; 
    proc sort data=&DSN out=Out; by &Start; 
     Run; 
    Data ctrl; 
     set Out(rename=(&Start=label &Label=start)) end=last; 
     retain fmtname &fmtname type &type; 
     output; 
    If last then do; 
     hlo='O'; 
     label='*ERROR'; 
     output; 
    End; 
Run; 
%End; 
proc format library=myfmt cntlin=ctrl; 
Run; 
%Mend CreateFormat; 

這裏是控制數據集,通過它上面的宏應用於所述數據集的每個觀測和觀測值的值來運行是varibales輸入的代碼在宏...

Data OPER.format_control; 
Input DSN :$12. Label :$15. Start :$15. fmtName :$8. type :$1. fmt_Startdt :mmddyy. fmt_Enddt :mmddyy.; 
format fmt_Startdt fmt_Enddt date9.; 
Datalines; 
ssin.prd prd_nm prd_id mealnm n . 12/31/9999 
ssin.prd prd_id prd_nm mealid c . 12/31/9999 
ssin.fac fac_nm onesrc_fac_id fac1SRnm n . 12/31/9999 
ssin.fac fac_nm D3_fac_id facD3nm n . 12/31/9999 
ssin.fac onesrc_fac_id D3_fac_id facD31SR n . 12/31/9999 
oper.wrkgrp wrkgrp_nm wrkgrp_id grpnm n . 12/31/9999 
; 

回答

0

這樣的事情。

proc sql; 
select catx(',',cats('%CreateFormat(',DSN),Label,Start,fmtname,cats(type,')'); 
into :formcreatelist separated by ' ' 
from oper.format_control; 
quit; 

你可能需要把你的一些變量放到你想要的宏變量中。我在這裏使用了略帶挑釁性的貓/貓咪組合,你可以在一次又一次加入'''的貓。

這裏你有一個限制 - 在一個宏變量中總共大約20,000個字符。如果結束了,你必須使用CALL EXECUTE(它具有一些古怪的功能),或者你可以把宏調用放入一個文本文件中並且%INCLUDE。

0

有一個更好的方法來做到這一點,而不是選擇...到一個宏變量。使用像這樣的臨時文件:

filename dyncode temp; 

data _null_; 
    file dyncode; 
    set OPER.format_control; 
    put '%createformat ....'; 
run; 

%include dyncode; 

filename dyncode clear; 

此技術不受限於宏變量的32k長度限制。

請注意,您應該明確地使用%createformat的單引號來防止SAS在數據步驟編譯之前調用宏。您希望宏在%include運行時運行。

上述方法類似於調用execute,但調用execute是邪惡的,因爲它不按預期的順序在宏內執行宏和嵌入的數據/ proc代碼。避免通話執行。

最後,如果您正在運行交互式SAS並使用該技術,則可以使用一種巧妙的技巧進行調試。註釋掉最後兩行代碼 - 包含和文件名清除。運行其餘代碼後,在命令窗口中輸入SAS命令「fslist dyncode」。這將彈出您剛剛生成的動態代碼的記事本視圖。你可以查看它,並確保你有你想要的。

+0

我已經發布了一個示例調用執行的解決方案。這是否會以與您的解決方案不同的順序運行宏的迭代? – user667489 2013-12-15 00:02:30

+0

調用執行將在您的解決方案中以正確的順序在宏步驟中運行。所以不用擔心。然而,調用執行有時候會以一種意想不到的順序運行這個簡單的事實對我來說是可怕的,我現在完全避開它。以下是討論此問題的一篇論文:http://www2.sas.com/proceedings/sugi22/CODERS/PAPER70.PDF 請參見第2/3頁的「調用宏的示例」一節。 – 2014-07-01 17:50:04

0

這裏有一個呼叫執行的解決方案,只是爲了完整性:

data _null_; 
    set OPER.format_control; 
    call execute('%CreateFormat(' || DSN || ',' || Label || ',' || Start || ',' || fmtname || ',' || type || ');'); 
run; 
相關問題