BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hello!

I suspect this problem has something to do with when the variable is being resolved, but I'm not sure how to solve it...

Here's a sample of the code I'm using:

********
%macro test(exlimitint);

%if &exlimitint= %then
%do;
%put variable is null;
%end;

%else
%do;
%put &exlimitint.;
%end;

%mend test;
***********

If I run this with a null value, it works fine. For example:

*********
%let exlimitint=;

%test(&exlimitint);
***********

...produces the following log

MLOGIC(TEST): Beginning execution.
SYMBOLGEN: Macro variable EXLIMITINT resolves to
MLOGIC(TEST): Parameter EXLIMITINT has value
SYMBOLGEN: Macro variable EXLIMITINT resolves to
MLOGIC(TEST): %IF condition &exlimitint= is TRUE
MLOGIC(TEST): %PUT variable is null
variable is null
MLOGIC(TEST): Ending execution.

If I run it with a the variable set to a simple value, it works fine. Like so...

***********
%let exlimitint=x;

%test(&exlimitint);
***********

...results in:

MLOGIC(TEST): Beginning execution.
SYMBOLGEN: Macro variable EXLIMITINT resolves to x
MLOGIC(TEST): Parameter EXLIMITINT has value x
SYMBOLGEN: Macro variable EXLIMITINT resolves to x
MLOGIC(TEST): %IF condition &exlimitint= is FALSE
MLOGIC(TEST): %PUT &exlimitint.
SYMBOLGEN: Macro variable EXLIMITINT resolves to x
x
MLOGIC(TEST): Ending execution.

However, if I try to set the variable to a value that contains a put statement (which is what I actually need), it bombs.

*********
%let exlimitint=if put(x,$intfmt)='FMT VALUE';

%test(&exlimitint);
*********

MLOGIC(TEST): Beginning execution.
SYMBOLGEN: Macro variable EXLIMITINT resolves to if put(x,$intfmt)='FMT VALUE'
MLOGIC(TEST): Parameter EXLIMITINT has value if put(x,$intfmt)='FMT VALUE'
SYMBOLGEN: Macro variable EXLIMITINT resolves to if put(x,$intfmt)='FMT VALUE'
ERROR: Required operator not found in expression: &exlimitint=
ERROR: The macro TEST will stop executing.
MLOGIC(TEST): Ending execution.

Thoughts, anyone?

Thanks!!!
Emily
2 REPLIES 2
Cynthia_sas
SAS Super FREQ
Hi:
Generally, folks don't pass whole IF statements in a %LET. Although it is possible to do, usually, you want to -do- something if a macro variable exists. Well, what is the thing you want to do?? Usually, it is some kind of conditional process, procedure or data step (or piece of data step program.)

I see that as one issue. Then there's the fact that you're passing an IF statement to a macro program and the IF statement will be hanging out in open code, unless you haven't shown the whole program. You can only use an IF statement inside a DATA step program. Don't confuse a data step IF with a macro logic %IF.

But, assuming that you haven't shown us all the code, and you are hiding a data step program someplace, I would expect to see a quoting function like %STR or %NRSTR being used to protect the IF statement snippet.

Even if you DO have a data step program, however, your PUT statement is incorrect. The FORMAT is missing a '.' -- it should be $INTFMT. (your syntax is missing the period. Also, the rest of your code will need to have the rest of the IF statement -- including the action to take on the TRUE and the closing semi-colon.

One rule of thumb for macro processing is to start with a working SAS program and then macro-ize the working program. I don't see that you have a working SAS program that can be macro-ized -- where is the rest of your IF statement going to be?? It seems to me that you want to do some kind of error checking -- which is a good thing, but I'd expect to see something like what's shown at the bottom of this posting -- I made up a program to show the difference between a macro %IF and a data step IF.

In my program, I show the %IF controllling whether an entire data step program would be run. Alternately, I could have coded the %IF -inside- the DATA step program, but generally error checking and issuing messages in the log is something that's done before a major process starts because if you don't have all of your macro variables with values, you might not want to go forward with the data step program.

cynthia

[pre]
%macro test(exlimitint);

%if &exlimitint= %then %do;
%put -------***** EXLIMITINT macro variable is null;
%end;
%else %if %upcase(&exlimitint) ne SEX %then %do;
%put -------***** You can only ask for the SEX variable;
%end;
%else %if %upcase(&exlimitint) eq SEX %then %do;
proc format;
value $intfmt 'M' = 'FMT VALUE'
'F' = 'XXXXXXXXX';
run;

data new;
set sashelp.class;
newvar = put(&exlimitint,$intfmt.);
if put(&exlimitint,$intfmt.)='FMT VALUE'
then output;
run;

ods listing;
proc print data=new noobs;
title 'Correct macro var and condition';
title2 "Value of EXLIMITINT macro var is: &EXLIMITINT";
run;

%end;

%mend test;

options nodate nonumber center;
** invoke with null;
%test()

** invoke with SEX (since program uses SASHELP.CLASS);
%test(sex)

** invoke with NAME -- not what program is coded for;
%test(name)
[/pre]
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
I do this all the time with SAS - using SAS macro variables as code exit-points but you need to surround your macro variable using %QUOTE (* your code goes here;);

Also, I encourage you to code your macro language %IF %THEN %-whatever-; statements so that there is never an unbalanced condition with the operator -- for readability I choose to use the . (period) character. Another technique if you are checking for a zero-length is to use the %LENGTH(&macrovar) and then do some logic accordingly.

And in some unique cases, you will need to call upon some of the more complex macro language functions for resolution. So I suggest you get familiar with the ins/outs of macro function and make extensive use of the most-valuable forum resources like Cynthia but more importantly get used to checking the SAS Support http://support.sas.com/ website for SAS-hosted DOC and supplemental technical and conference topic-related reference material.

Scott Barry
SBBWorks, Inc.

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
  • 2 replies
  • 10210 views
  • 0 likes
  • 3 in conversation