BookmarkSubscribeRSS Feed
sasiscool
Obsidian | Level 7

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!

4 REPLIES 4
Astounding
PROC Star

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.

sasiscool
Obsidian | Level 7

 

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!

sasiscool
Obsidian | Level 7

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;

Astounding
PROC Star

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.

SAS Innovate 2025: Register Today!

 

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.


Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1239 views
  • 0 likes
  • 2 in conversation