Sas 错误:%EVAL函数的参数中的IN运算符缺少操作数

Sas 错误:%EVAL函数的参数中的IN运算符缺少操作数,sas,eval,sas-macro,in-operator,Sas,Eval,Sas Macro,In Operator,在我的例子中,我不能理解这个错误,因为我可以执行宏,它工作得很好,我尝试在它给我这个错误10分钟后再次运行它,有时我执行它四次,第五次给我一个正确的结果。 这是我的密码: %let list = &Control_1. &Control_2. &Control_3. &Control_4. ; %macro print_control_2(list) / minop

在我的例子中,我不能理解这个错误,因为我可以执行宏,它工作得很好,我尝试在它给我这个错误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);

最好使用
%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()
引用列表,因为它可能包含未解析的宏变量。这可能会中断操作员的登录

还建议始终使用
minoperator
添加
mindelimiter
,因为用户可以使用autoexec设置自己的
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);

&control\u 1
-
&control\u 4
解析为什么?实际上,这是一个验证宏变量是否存在的列表,因为我有很多文件,每个文件都有一个特定的列表。您在operator中为宏设置了什么分隔符?无,由于它有时可以工作,我认为我不应该设置分隔符。您需要知道它使用的分隔符,以了解它是否能够在IN运算符的右侧看到正确数量的值。我认为如果不在宏中设置分隔符,那么它使用的将取决于系统设置,如果在调用之间更改分隔符,系统设置可能会有所不同。您确定IN运算符的两边都有值吗?谢谢您的回答,这正是我的问题(我有未解析的宏变量),并且%bquote()解析了它,因此宏现在可以完美地工作。但是我仍然不明白为什么它有时有效,有时不添加任何修改就不行。可能是因为有时它们在您的环境中都会解决,有时则不会。如果您在与上面相同的精确参数下运行,并且有多个结果,那么很遗憾,我不确定。每次都会给我一个错误。