SAS - 在宏条件之前分配库

时间:2017-03-27 20:57:39

标签: sas sas-macro

我在宏中使用条件逻辑时出错并分配了我的库...

我的问题: 我在分配库之前执行了条件宏逻辑(%IF /%THEN%DO)语句,逻辑基于库中是否存在数据集。

我还在学习SAS中的宏,我不知道如何确保首先分配我的库...

我的程序看起来像这样:

%MACRO MyProg();
    SIGNON...
    RSUBMIT....
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;


    %IF %SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO;
    ....some datasteps....
    %END;

ENDRSUBMIT;
SIGNOFF;
%MEND;

%MyProg();

我可以从日志中看到%IF &SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO;为假,然后在之后分配了库。

如何确保始终首先执行Libname语句?

1 个答案:

答案 0 :(得分:2)

这里的问题是本地宏处理器在将其交给SAS / CONNECT服务器之前正在处理宏语法。那么当%MyProg()执行时首先发生的事情是,其中的所有文本都被视为作为文本并进行处理 - 返回此信息:

SIGNON...
    RSUBMIT....
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;
    ....maybe some datasteps or not depending on what happened _locally_ with %if ....
    ENDRSUBMIT;
SIGNOFF;

这是正确的行为,通常非常有用。在很多情况下,您可能希望根据本地内容提交不同的RSUBMIT代码块。但是,它不是想要的。

您需要使用宏引用以防止在您想要之前解析宏。我不是百分之百确定这里的时间,但我认为%nrbquote可能是正确的引用函数。

但是,您还有一个问题,即%IF需要位于远程计算机上的宏 中。请记住,RSUBMIT所做的是提交另一个SAS.EXE(或unix / vax / etc.等效)要处理的代码。因此,如果您希望它处理%if [something],则必须在内部宏。所以你真正需要的是:

SIGNON;
RSUBMIT;
%MACRO MyProg();
    LIBNAME TEMP "My.Qualifiers.To.Location" Disp=shr;


    %IF %SYSFUNC(EXIST(TEMP.FILE)) %THEN %DO;
    ....some datasteps....
    %END;

%MEND;


%MyProg();
ENDRSUBMIT;
SIGNOFF;

正如汤姆在对this answer的评论中指出的那样,这并不总是安全的 - 提交一个宏可能很危险,因为它并不总是正确解析 - 所以要谨慎对待它,并且或许可以考虑是否可以通过不使用宏语言的其他方式处理,或者%include来自驻留在SAS / CONNECT服务器上的文件中的宏。