BookmarkSubscribeRSS Feed
loishaggard
Fluorite | Level 6

I am looking at some SAS code that has these lines:

 

%if UPCASE('%cross1%') != 'YEAR' %then %do;
if year_sflag<=0 then delete;
%end;

 

Does "!=" make sense? "or, equals"? It doesn't throw an error, but I can't imagine it is correct.

 

Has anyone seen/used this expression? If so, what does it do?

 

Thank you!

 

8 REPLIES 8
Reeza
Super User
!= is not equals.

Your UPCASE is wrong though, it needs to be wrapped in %SYSFUNC().
loishaggard
Fluorite | Level 6
Thanks. I thought the bang operator was "OR." But if it's combined with an equals sign it is "not equals".

Go figure.

Thanks.
Reeza
Super User

This is SQL standard, not SAS, but it works. I think at one point it was interpreted as less than but that changed.

A good check is to see the log, which translates it and shows the code actually executed. Add the following before your program, execute your program and check your log around that line to see what it displays.

options mprint symbolgen mlogic;

 


EDIT: The pipe | operator is an OR, Bang (!) exclamation marks are NOT in most languages. 

 

jimbarbour
Meteorite | Level 14

@loishaggard wrote:

I am looking at some SAS code that has these lines:

 

%if UPCASE('%cross1%') != 'YEAR' %then %do;
if year_sflag<=0 then delete;
%end;


The != makes sense to me, it's the rest of the code that doesn't make sense to me.  🙂  At a minimum, %SYSFUNC (or %QSYSFUNC) needs to be added before the UPCASE().  But %cross1% is in single quotes which makes it a literal in SAS.  SAS is not going to try to convert it to anything, so it will never be equal to 'YEAR'.  Is there some other kind of pre-processing going on?  %cross1% looks like a Windows variable name of the type that would be used in a .bat or .cmd file.  I'm a little sleepy today, but I don't recall a SAS syntax that uses a %var_name% format.

 

Jim

loishaggard
Fluorite | Level 6
Yes, pre-processing by a C program that is writing the SAS code.
jimbarbour
Meteorite | Level 14

Interesting.

 

The C code is writing SAS code that will alter itself based on certain values.  Very sophisticated!

 

This macro IF statement conditionally includes a regular IF statement into a DATA step:

%if UPCASE('%cross1%') != 'YEAR' %then %do;
if year_sflag<=0 then delete;
%end;

 

If the macro IF statement is true, then the following IF statement will be part of the DATA step.  Otherwise, it will not.

if year_sflag<=0 then delete;

 

However, I am pretty sure that it's not working correctly as is.  Since the "UPCASE('%cross1%')" does not have a %SYSFUNC, SAS should handle "UPCASE('%cross1%')" as text.  In other words, SAS is literally comparing "UPCASE('%cross1%')" with "'YEAR'".  Even if the C program changes %cross% to a value, SAS is still comparing the letters U, P, C, A, S, and E as part of the comparison.  UPCASE is not treated as a function without %SYSFUNC; it is treated as text.  Also, note that the single quotes around "YEAR" are part of the text that SAS will compare.  

 

Since the text "UPCASE('%cross1%')" will always be not equal to "'YEAR'", the DATA step IF statement will always be included, and if the Year_Sflag is <= 0, then that record will be dropped.

 

As coded, the macro IF statement is superfluous because the text "UPCASE('%cross1%')" will always be not equal to the text "'YEAR'".  You could leave the macro IF statement out and have the same results.  However, that may not be what you want.  If you truly want the resolved value of "'%cross1%'" to be converted to upper case and compared to the literal, then you need to add a %SYSFUNC or %QSYSFUNC.  Either way, the code should be tested because you will most likely be changing the behavior of the program.

 

Jim

loishaggard
Fluorite | Level 6
Yes. The UPCASE is something I added when I was experimenting with it. I implemented your suggestion, now.

This code is using in a web-based query application. The front end passes name-values pairs to the back end C program in a URL. The C program reads the name-value pairs and plugs in values for variables like %cross1%.

Thanks for your help.

L
Tom
Super User Tom
Super User

!= is gibberish. You can use ^= or ~= (or if you are on a mainframe the actual not character) or not = 

397   data test;
398     set sashelp.class ;
399     where age ~= 13;
400   run;

NOTE: There were 16 observations read from the data set SASHELP.CLASS.
      WHERE age not = 13;
NOTE: The data set WORK.TEST has 16 observations and 5 variables.

But I am not sure why SAS macro is not throwing an error on that expression.

To the macro processor %EVAL() function the ! is just the last character in the string to the left of the equal sign.

 

Why not have the program that is evaluating the %name% syntax just test the value and then conditionally generate the SAS code instead of trying to use the SAS macro processor?

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 8 replies
  • 606 views
  • 1 like
  • 4 in conversation