2013-02-12 86 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; 
相关问题