Search code examples
sasevalsas-macroin-operator

ERROR: Operand missing for IN operator in argument to %EVAL function


I can't understand this error in my case since i can execute the macro and it works perfectly and i try to run it again 10 minutes after it give me this error and sometimes i execute it four times the fifth one give me a correct result. here is my code :

%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);

Solution

  • It is better practice to use %symexist() to check if macro variables exist to keep the log clean. If you have a list of variables to check, you can loop through your list of macro variables. By default, countw() and %scan() will see spaces as a delimiter.

    %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);
    

    To solve your issue specifically, you will need to quote your list with %bquote() since it may contain unresolved macro variables. This can break the IN operator.

    It is also recommended to always add mindelimiter with minoperator since users are able to set their own mindelimiter default with an autoexec. This will guarantee that your expected delimiter is always used.

    %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);