0

这是宏代码......

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;

这是控制数据集的代码,上述宏应通过该代码对数据集的每个观察值运行,并且观察值的值是宏中变量的输入....

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
;
4

3 回答 3

0

像这样的东西。

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

您可能需要 PUT 一些变量才能将所需的格式放入宏变量中。我在这里使用稍微笨拙的猫/catx 组合,你可以用 ',' 加多次猫一次。

您在这里确实有一个限制 - 宏变量中总共有大约 20,000 个字符。如果结束了,您要么必须使用 CALL EXECUTE(它具有一些古怪的功能),要么可以将宏调用放入文本文件并 %INCLUDE 。

于 2013-02-12T20:59:27.220 回答
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 是邪恶的,因为它没有按预期顺序执行宏和宏中嵌入的data/proc 代码。避免调用执行。

最后,如果您正在运行交互式 SAS 并使用该技术,那么您可以使用一个巧妙的技巧进行调试。注释掉最后两行代码——明确的包含和文件名。运行剩余代码后,在命令窗口中输入 SAS 命令“fslist dyncode”。这将在您刚刚生成的动态代码上弹出一个记事本视图。您可以查看它并确保您得到了您想要的。

于 2013-09-02T20:42:56.337 回答
0

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

data _null_;
  set OPER.format_control;
  call execute('%CreateFormat(' || DSN || ',' || Label || ',' || Start || ',' || fmtname || ',' || type || ');');
run;
于 2013-12-15T00:00:38.247 回答