我在宏中使用条件逻辑时出错并分配了我的库...
我的问题: 我在分配库之前执行了条件宏逻辑(%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语句?
答案 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服务器上的文件中的宏。