I have a macro loop that spits out reports. However, I want to include an %if %then clause to conditionally change my proc report slightly under certain conditions.
Code:
%macro TSDS_ERROR (tsdselement);
%let k=1;
%let error = %scan(&tsdselement,&k,'*'); /*picks the first error in list we have */
%do %while ("&error" ^= ""); /*loop until the list is done*/
%if &error=ContactHr %then %do;
proc report 1 code.......
%end;
%else %do;
proc report 2 code.......
%end;
%let k = %eval(&k + 1); /* redfine the value of k so that the loop continues the 2nd ,3rd, etc. word in the list*/
%let error = %scan(&tsdselement,&k,'*');
%end;
%mend;
%TSDS_ERROR (ContactHr*apple*Loc-orange*....);
However, I get the common Error:
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
&error=ContactHr
ERROR: The macro TSDS_ERROR will stop executing.
I have some articles on the topic, but stil can't seem to get passed this error, so that it will accept characters. Any Advise?
Thanks again SAS forums!
The problem arises because some strings in your list can contain a dash. Consider how SAS interprets this:
%if Loc-orange = ContactHr %then %do;
Macro language interprets the dash as a request to perform subtraction, giving you your error message. The simplest fix might be this:
%let error = "%scan(&tsdselement,&k,*)";
Note that you don't need quotes around the * in macro language (unless you want quotes to be used as a delimiter by %SCAN).
Now the comparison would become:
%if &error ne "ContactHr" %then %do;
Double quotes suppress the interpretation of a dash as subtraction.
Also, you might need to check the proper construction of your %DO %WHILE condition, but a little experimentation should let you work that out.
i do want the quotes to be used as a delimiter for the %scan. The delimiter in this list is '*'
why must the logic be inversered rather than direct?
%if &error ne "ContactHr" %then %do;
Sure, this can get my where I need to go by reverse, but I am still uncelar as to why a plain &error=ContactHr will not work?
thanks again!
i had a compress statement noted out for some reason, which is where the '-' snuck in. I didn't even realize when I copied it over. Thanks for spotting that.
However, my new problem, is that my loop only creates the report for the first %if %then:
%if &error=ContactHr %then %do;
proc report 1
%end;
%else %do;
proc report2
%end;
In reality, I have several %if statements that I need fulfilled. For instance:
%if &error=ContactHr %then %do;
proc report 1
%end;
%else %if &error=table %then %do;
proc report2
%end;
...
going on like that.
However, I cannot get it to move past the first itineration of %if %then. It satitifies then doesn't move to the next %if %then, which leads me to think it closing the loop early.
again full code:
%let k=1;
%let error = %scan(&tsdselement,&k,'*'); /*picks the first error in list we have */
%do %while ("&error" ^= ""); /*loop until the list is done*/
%if &error=ContactHr %then %do;
proc report 1
%end;
%else %if &error=table %then %do;
proc report 2
%end;
/*Error list loop*/
%let k = %eval(&k + 1); /* redfine the value of k so that the loop continues the 2nd ,3rd, etc. word in the list*/
%let error = %scan(&tsdselement,&k,'*');
%end;
%mend;
The reason concerns how an %IF condition interprets a dash. Remember, %EVAL is applied to all %IF conditions. Thus if a dash is present, it triggers the attempt to subtract.
Consider a simple case:
%let club = 4-H;
%if &club = 4-H %then %do;
Assuming these statements are contained within a macro definition (so %IF is legal), the first statement always works. And the second statement always generates an error. The dash triggers %EVAL to perform subtraction. However, this comparison would work:
%if "&club" = "4-H" %then %do;
By adding the double quotes, %EVAL now figures out it should perform a character comparison and not attempt to subtract.
This post was in response to your post #3. Regarding your post #4, try inserting some diagnostics. After assigning a value to &error, display the value with a %PUT statement. Better yet, turn on debugging options such as MLOGIC and SYMBOLGEN.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.