【问题标题】:ERROR: Operand missing for IN operator in argument to %EVAL function错误:%EVAL 函数的参数中缺少 IN 运算符的操作数
【发布时间】:2020-08-12 13:54:17
【问题描述】:

在我的情况下我无法理解这个错误,因为我可以执行宏并且它运行良好,我尝试在它给我这个错误后 10 分钟再次运行它,有时我执行它四次给我第五次一个正确的结果。 这是我的代码:

%let list = &Control_1. 
            &Control_2. 
            &Control_3.
            &Control_4.
            ;
%macro print_control_2(list) / minoperator ; 
%let Control_2=Control_2;

     %IF  &Control_2. in &list. %THEN %DO;
          proc sql;
          ...
         ;quit;
     %end; 
%mend;

%print_control_2(&list);

【问题讨论】:

  • &control_1-&control_4 解决了什么问题?
  • 实际上是一个验证宏变量是否存在的列表,因为我有很多文件,每个文件都有一个特定的列表。
  • 宏 IN 运算符的分隔符设置了什么?
  • 无,因为它有时会起作用,我认为我不应该设置分隔符。
  • 您需要知道它使用什么分隔符才能了解它是否会在 IN 运算符右侧看到正确数量的值。我认为如果您没有在宏中设置分隔符,那么它使用的将基于系统设置,如果您在调用之间更改它可能会有所不同。你确定你在 IN 运算符的两边都有价值观吗?

标签: sas eval sas-macro in-operator


【解决方案1】:

最好使用%symexist() 检查是否存在宏变量以保持日志干净。如果您有要检查的变量列表,则可以遍历宏变量列表。默认情况下,countw()%scan() 会将空格视为分隔符。

%let list = Control_1
            Control_2
            Control_3
            Control_4
            ;

%let Control_2 = Control_2;

%macro print_control_2(list);
    %do i = 1 %to %sysfunc(countw(&list.) );
        %let control = %scan(&list., &i.);

        %if(%symexist(&control.) ) %then %put &control. exists.;

    %end;
%mend;
%print_control_2(&list);

为了具体解决您的问题,您需要使用%bquote() 引用您的列表,因为它可能包含未解析的宏变量。这可能会破坏 IN 运算符。

还建议始终添加mindelimiterminoperator,因为用户可以使用自动执行设置自己的mindelimiter 默认值。这将保证始终使用您预期的分隔符。

%macro print_control_2(list) / minoperator mindelimiter=' '; 
     %IF  &Control_2. in %bquote(&list.) %THEN %DO;

        %put &control_2. exists.;

     %end; 
%mend;

%print_control_2(&list);

【讨论】:

  • 感谢您的回答,这正是我的问题(我有未解决的宏变量)并且 %bquote() 解决了它,因此宏现在可以完美运行。但是仍然不明白为什么它有时会起作用,有时如果不添加任何修改则不起作用
  • 可能有时它们都解决了,有时它们在您的环境中没有。如果您在与上述相同的确切参数下运行多个结果,那么不幸的是我不确定。它每次都给我一个错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多