0
votes

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);
1
What do &control_1-&control_4 resolve to? - Stu Sztukowski
actually it's a list to verify if the macro variable exist, since i have a lot of files and there is a specific list for every. - Mlk
What have you set as the delimiter for macro IN operator? - Tom
None, and since it works some times i think that i shouldn't set a delimiter. - Mlk
You need to know what delimiter it is using to understand whether it is going to see the right number of values on the right side of the IN operator. I think if you don't set the delimiter in the macro then what it uses will be based on the system setting, which could vary if you change it between calls. Are you positive you have values on both sides of the IN operator? - Tom

1 Answers

1
votes

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