如何为sas数据集中的每个观察执行宏?

时间:2013-02-12 20:25:37

标签: sas sas-macro

这是宏代码.....

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
;

3 个答案:

答案 0 :(得分:0)

像这样。

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

您可能需要将一些变量PUT以获得所需的格式到宏变量中。我在这里使用略显笨拙的cat / catx组合,你可以用猫做一次','也加入了很多次。

这里有一个限制 - 宏变量总共约20,000个字符。如果它已经结束了,你要么必须使用CALL EXECUTE(它有一些古怪的功能),要么你可以把宏调用放到一个文本文件中,%INCLUDE它。

答案 1 :(得分: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”。这将弹出您刚刚生成的动态代码的记事本视图。你可以查看它并确保你得到你想要的东西。

答案 2 :(得分:0)

这是一个调用执行解决方案,只是为了完整性:

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