Hi, I cannot for the life of me understand why my macro is acting this way.
Context: I am creating a macro to conditionally generate reports depending on the macro variable lReportNum. Below is a snippet of my code.
%if &lReptNum. in (1,2,3,4) %then
%do;
[proc report.. more sas code...]
%end;
For some strange reason, when opening a new SAS session and '%include'ing my macro to run it, I always get the following result from the first run:
SYMBOLGEN: Macro variable LREPTNUM resolves to 1
MLOGIC(PMREPORT_YOY): %IF condition &lReptNum. in (1,2,3,4) is FALSE
I don't understand why my condition is giving me FALSE. Here's the strange part: when I %include my macro again and run it a second time, I get the following result:
SYMBOLGEN: Macro variable LREPTNUM resolves to 1
MLOGIC(PMREPORT_YOY): %IF condition &lReptNum. in (1,3,5,7) is TRUE
Note that this results only if I %include my macro a second time. I am not sure why this is happening. Any insight or help would be appreciated.
The IN operator is a recent addition to macro code. As such you need to make sure that you have set system options properly if you want to use it.
I suspect that your first attempt is changing this setting so that your second attempt then works.
That said your syntax does not look correct. Here is example from page linked above.
%put %eval(a IN a b c d);
Why do you have the parentheses? Also did you make sure to set the delimiter to comma instead of space?
The IN operator is a recent addition to macro code. As such you need to make sure that you have set system options properly if you want to use it.
I suspect that your first attempt is changing this setting so that your second attempt then works.
That said your syntax does not look correct. Here is example from page linked above.
%put %eval(a IN a b c d);
Why do you have the parentheses? Also did you make sure to set the delimiter to comma instead of space?
Hi Tom, thanks for your reply.
I found the solution. I had already set the following system options properly
options
minoperator
mindelimiter=',';
but I had set them inside the macro that conditionally generates the report. I moved the above options code outside the macro, and my code worked on the first run.
Just a follow-up question if you don't mind, do you know why setting the system options inside the macro caused my code to work on only the second time after %include'ing a second time?
Thanks again.
@cashsas wrote:
Hi Tom, thanks for your reply.
I found the solution. I had already set the following system options properly
options
minoperator
mindelimiter=',';but I had set them inside the macro that conditionally generates the report. I moved the above options code outside the macro, and my code worked on the first run.
Just a follow-up question if you don't mind, do you know why setting the system options inside the macro caused my code to work on only the second time after %include'ing a second time?
Thanks again.
A guess without seeing the entire macro code would be that the options were set after the first use of the in operator. If the include file had multiple macros it might be the order they were called for use such that the macro with the options wasn't called before another macro that used the option. Just defining a macro with the options wouldn't set them until the macro was executed at least once.
When you set the options makes a difference.
It is the setting when CALL the macro that makes the difference.
120 %macro test ; 121 %if x in a b c %then %put found ; %else %put not found ; 122 %mend test; 123 124 125 options nominoperator; 126 %put %sysfunc(getoption(minoperator)); NOMINOPERATOR 127 %test; ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: x in a b c ERROR: The macro TEST will stop executing. 128 129 options minoperator; 130 %put %sysfunc(getoption(minoperator)); MINOPERATOR 131 %test; not found
Note that if you use the options on the %MACRO statement then your macro will not depend on the system option.
156 %macro test / minoperator; 157 %if x in a b c %then %put found ; %else %put not found ; 158 %mend test; 159 160 161 options nominoperator; 162 %put %sysfunc(getoption(minoperator)); NOMINOPERATOR 163 %test; not found 164 165 options minoperator; 166 %put %sysfunc(getoption(minoperator)); MINOPERATOR 167 %test; not found
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.