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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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