由于在SAS中误用%sysrput而导致的奇怪错误

由于在SAS中误用%sysrput而导致的奇怪错误,sas,Sas,我正在将AIX6.1与SAS 9.1.3一起使用 我有一个在PC SAS 9.1中运行的程序 该程序将重新提交到unix。 现在,我将程序转换为完全在AIX6.1中运行 程序异常失败。 经调查,这是由于%sysrput 以下是该程序的简化版本: options mPrint mLogic symbolGen ; %macro combine( startdate= , fullprefix= ); data _null_ ; call symput( 'plength'

我正在将AIX6.1与SAS 9.1.3一起使用
我有一个在PC SAS 9.1中运行的程序
该程序将重新提交到unix。
现在,我将程序转换为完全在AIX6.1中运行
程序异常失败。
经调查,这是由于%sysrput
以下是该程序的简化版本:

options mPrint mLogic symbolGen ; 
%macro combine( startdate= , fullprefix= );
  data _null_ ;   
       call symput( 'plength',compress(length(compress("&fullprefix."))));
  run;  
  data _null_ ;   
       length balance 8. ;  
              balance= 1 + &plength.; 
  run;  
%mEnd;  
data _null_ ;
     call symput( 'refdate', put(today(),date9.));   
run;
%put &refdate.;   
* -- If I forget to comment out the sysrput, the plength cannot be resolved -- ;
%sysrput refdate=&refdate.; 
%put &refdate.;   
%combine( startdate= "&refdate."d, fullprefix=a_filename_prefix );   
(很抱歉,这些文字没有意义,我只想做一个演示。)

实际上,在AIX中,我不应该使用%sysrput
我只是忘了把它评论出来。
但是,如果我忘记了这一点,balance=语句中的第plength宏变量将出错。这很奇怪

要解决此问题,只需注释掉%sysrput即可

但是,有人知道为什么%sysrput会导致宏中的宏变量失败吗


Alvin SIU

很难从问题的简化版本中分辨出来,但如果您要问为什么宏变量
plength
在宏执行后不存在,那是因为您必须在宏代码本身中将其定义为全局。换言之:

%macro combine( startdate= , fullprefix= );
%global plength;
...
%mend;
是的,如果您在不受SAS/CONNECT控制的SAS会话中使用
%SYSRPUT
命令,您将得到一个SAS错误;如果出现SAS错误,非交互式会话将进入“语法检查”模式,在这种情况下,程序中的其余语句将无法完全执行


最后一位是将代码从SAS/CONNECT环境转换为“普通旧SAS”时常见的误解。当您使用SAS/CONNECT时,连接的“服务器”端将使用“-NOSYNTAXCHECK”选项启动。

经过一些小测试的调查。也许这就是答案

实际上,我将在所有批处理SAS程序中使用选项ERRORABEND,以在出现错误时停止SAS。这适用于许多错误和函数

%SYSRPUT语句确实发出错误消息说。。。选项DMR…
但是程序不会停止在这里。
它没有给出任何信息说。。。OBS=0…
就这样继续下去。 因此,我只是“认为”这是一个小错误,就像LIBNAME是一个不存在的目录,SAS将“正常”继续运行一样。
(顺便说一句,我认为SYSRPUT错误已经在没有任何通知或提示的情况下悄悄地打开了语法检查模式。)

下一个%PUT语句是正常的,与上一个语句的值相同。
这使我误以为程序运行正常

接下来的陈述也是正常的。有许多SYMBOLGEN、MPRINT和MLOGIC消息。
所以,这进一步误导了我,程序运行非常正常

在call symput plength语句之后,有一个注释:数值已被转换…
这进一步误导了我,程序运行正常

到目前为止(在这么多看起来像正常消息的消息之后),有一条注释说SAS set option OBS=0…
(此注释可能仅在RUN语句之后出现。)

此OBS=0消息实际上是提示SAS正在使用语法检查模式的提示。
此OBS=0可能是由SYSRPUT错误引起的。但是,由于在SYSRPUT错误之后有太多看起来像普通消息的消息,所以我忽略了这条OBS=0消息。
实际上,调用symput非常简单,不应该导致任何错误。
这只会使局势进一步复杂化

由于SAS处于语法检查模式,这就是导致balance语句中的plength变量出现类似错误的原因

事情就是这样


无论如何,为了避免进入这种复杂和误导的情况,请记住注释掉所有%SYSRPUT将要做的事情。

当您包含它时,SYSRPUT是否会给出错误,或者它是否有效?执行第二个%put&refdate。看起来正确吗(与第一个相同)?我也在帖子发布后数小时想出了这个语法检查模式。有了你的评论,我就直奔这个方向,也许最终会得到答案。整个故事有点长,注释字段中没有足够的字符来讲述。所以,我用答案回答你的问题,希望它会有足够的空间。不管怎样,谢谢你的帮助。这完全是不可理解的。