SAS - 在宏条件之前分配库

SAS - Assign Library before Macro Conditionals

我在宏中的条件逻辑和分配我的库时遇到问题...

我的问题: 我在分配库之前执行条件宏逻辑 (%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;是false,然后再分配库

如何确保 Libname 语句总是首先执行?

您的问题是本地宏处理器在将宏语法传递给 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 代码块。然而,这不是想要的。

您将需要使用宏引用,以防止宏在您希望的情况下被解析。我不是 100% 确定这里的时间,但我认为 %nrbquote 可能是要使用的正确引用函数。

但是,您还遇到了问题,即 %IF 需要位于远程计算机 的宏 中。请记住,RSUBMIT 所做的是提交另一个 SAS.EXE(或 unix/vax/etc。等效)将要处理的代码。所以如果你想让它处理 %if [something] 它必须是 inside 一个宏。所以你真正需要的是:

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;

正如 Tom 在对 的评论中指出的那样,这并不总是安全的 - 提交宏可能很危险,因为它并不总是被正确解析 - 所以谨慎行事,也许考虑一下这是否可以用另一种方式处理,不使用宏语言,或者 %include 从驻留在 SAS/CONNECT 服务器上的文件中获取宏。