BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hello Folks,

 

running this code:

 

%macro debug;

%LET _doDebug  = no;

%IF condition &_doDebug >= 1 %THEN %DO;

%PUT &=_doDebug;
%PUT PLEASE DO DEBUG THIS CODE!;

%END;


%ELSE %DO;
%PUT &=_doDebug;
%PUT DO NOT DEBUG!;
%END;

%mend;

%debug

I would expect the macro to abort with an error stating

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
condition &_doDebug >= 1
ERROR: The macro DEBUG will stop executing.

However, it runs perferctly fine, although with an outcome that is not desired, namly to set the if condition to TRUE:

MLOGIC(DEBUG):  %IF-Bedingung condition &_doDebug >= 1 ist TRUE

Why does SAS this? How can SAS equate a character expression with a numeric expression?

 

Also, wenn assigning the value "do not debug" to the macro variable "_doDebug " the macro does, what I expected:

 

30         %macro debug;
31         
32         %LET _doDebug  = do not debug;
33         
34         %IF condition &_doDebug >= 1 %THEN %DO;
35         
36         %PUT &=_doDebug;
37         %PUT PLEASE DO DEBUG THIS CODE!;
38         
39         %END;
40         
41         
42         %ELSE %DO;
43         %PUT &=_doDebug;
44         %PUT DO NOT DEBUG!;
45         %END;
46         
47         %mend;
48         
49         %debug
MLOGIC(DEBUG):  Ausführung beginnt.
MLOGIC(DEBUG):  %LET (Variablenname ist _DODEBUG)
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
       condition &_doDebug >= 1 
ERROR: The macro DEBUG will stop executing.
MLOGIC(DEBUG):  Ausführung wird beendet.

Can someone enlighten me?

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

As others have explained, macro language is perfectly capable of making this comparison:

 

%if c >= 1 %then %do;

There is an order to all characters (different for ASCII-based systems vs. EBCDIC), and macro language evaluates "c" and "1" as characters.

When you change the comparison by adding the word "not" it affects how macro language evaluates your request:


%LET _doDebug  = do not debug;
%IF condition &_doDebug >= 1 %THEN %DO;

Now macro language sees:

%IF condition do not debug >= 1 %then %DO;

While I haven't tested to be sure, the word NOT affects the comparison, forcing that part of the logic to be evaluated first.  In effect, macro language evaluates:

%IF condition do (not (debug >= 1)) %then %DO;

By evaluating the innermost portion of the comparison first, macro language next sees one of these (depending on whether the comparison is true or false):

%IF condition do 1 %then %DO;

%IF condition do 0 %then %DO;

That's the point where macro language gets confused and thinks you have entered an illegal %IF condition.

 

I'm not sure this is particularly useful, but it should explain the second part of your question about why you get an error message when you add NOT into the mix.

View solution in original post

8 REPLIES 8
PaigeMiller
Diamond | Level 26

The macro processor is simply a text processor. So

 

%IF condition &_doDebug >= 1 %THEN %DO;

resolves to comparing text string "condition no" to be greater than or equal to the text string "1", which is true when comparing text strings.

--
Paige Miller
FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hi @PaigeMiller ,

 

you are right: the macro processor is just a text processor. But how can this text processor evaluate a comparisson between two strings ? If I understand you correctly, then this processor does not recognize the string "1" as a number, but rather as a string of length 1. Also it recognizes the string "no" as a string of length 2.

 

Does the condition resolve to TRUE because it compares THE LENGTH of the strings, namly 2>= 1 and therefore resolves to TRUE?

PaigeMiller
Diamond | Level 26

The length of the string is not what is being compared. The content of the strings themselves are being compared, using an alphabetical sorting to do the comparison.

 

The string "condition no" is greater than the string "1" when compared alphabetically.

--
Paige Miller
Kurt_Bremser
Super User

The "left" part of the comparison is not the 2-character string "no", but the 12-character string "condition no".

Anyway, since all letters (uppercase and lowercase) come after the digits in the ASCII table, this comparison will always resolve to true, because "c" > "1".

Astounding
PROC Star

As others have explained, macro language is perfectly capable of making this comparison:

 

%if c >= 1 %then %do;

There is an order to all characters (different for ASCII-based systems vs. EBCDIC), and macro language evaluates "c" and "1" as characters.

When you change the comparison by adding the word "not" it affects how macro language evaluates your request:


%LET _doDebug  = do not debug;
%IF condition &_doDebug >= 1 %THEN %DO;

Now macro language sees:

%IF condition do not debug >= 1 %then %DO;

While I haven't tested to be sure, the word NOT affects the comparison, forcing that part of the logic to be evaluated first.  In effect, macro language evaluates:

%IF condition do (not (debug >= 1)) %then %DO;

By evaluating the innermost portion of the comparison first, macro language next sees one of these (depending on whether the comparison is true or false):

%IF condition do 1 %then %DO;

%IF condition do 0 %then %DO;

That's the point where macro language gets confused and thinks you have entered an illegal %IF condition.

 

I'm not sure this is particularly useful, but it should explain the second part of your question about why you get an error message when you add NOT into the mix.

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Thank you all, guys.

 

I really did learn something today!

 

Now I am keen on telling my coworkers! I'm sure, they are as surprised as I was to learn that 

%if c >= 1 %then %do;

is a perfectly fine expression in SAS 🙂

 

Cheers,

FK1


 

Kurt_Bremser
Super User

@FK1 wrote:

Thank you all, guys.

 

I really did learn something today!

 

Now I am keen on telling my coworkers! I'm sure, they are as surprised as I was to learn that 

%if c >= 1 %then %do;

is a perfectly fine expression in SAS 🙂

 

Cheers,

FK1


 


It's correct syntax, but nonsense semantically (as it will always be true).

 

PS in a data step,

if c >= 1

compares the value stored in variable c with the literal value 1, which makes a lot of sense.

PaigeMiller
Diamond | Level 26

@FK1 wrote:

Thank you all, guys.

 

I really did learn something today!

 

Now I am keen on telling my coworkers! I'm sure, they are as surprised as I was to learn that 

%if c >= 1 %then %do;

is a perfectly fine expression in SAS 🙂

 

Cheers,

FK1


 


I think the point is that macro variables and values can be compared alphabetically, so that you can find text strings that come earlier or later in the alphabet. Which of course could have many real-world uses. Here's a trivial example:

 

%let a=vanilla;
%let b=chocolate;
%if &a > &b %then %do; %put TRUE; %end;
%else %do; %put FALSE; %end;

But if your example is comparing a text string the the constant value 1, well I don't see any real-world uses here.

--
Paige Miller

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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
  • 8 replies
  • 1752 views
  • 4 likes
  • 4 in conversation