BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
BTAinRVA
Quartz | Level 8

Okay, maybe it's me. I have the code below and want the macro to determine date ranges based on the MissionNum variable. But it seems the if &MissionNum = 'MISSION1' then line is causing SAS to create a variable named MISSION1 in the resulting table. Is there some other way I should be referencing the MissionNum variable?

 

 

%Let DMISID = 0091;

%Let MissionNum = MISSION1;

%LET i = %sysfunc(substr(&MissionNum,8,1));

 

data test;

set twenthrappntfin;

length Period $6.;

informat Period $6. ;

format Period $6. ;

if DMISID= &DMISID;

 

 

if &MissionNum = 'MISSION1' then DO;

if fm in (7 8 9 10 11 12) and fy= 2012 then Period = 'Before' ;

else if fm in (2 3 4 5 6 7) and fy= 2013 then Period='After';

end;

END;

 

 

Thanks,

Brian

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

Be careful with your terminology with variable vs macro variable. 

 


@BTAinRVA wrote:

What I want it to do is evaluate the MissionNum variable to see if it is equal to MISSION1 , MISSION2, MISSION3, etc. s


 

I think you mean that you want to check if the value stored in the macro variable MissionNum is equal to MISSION1?

 

If so, this will work, but note the comparison is case sensitive. If you want it to be case insensitive, wrap it in lowcase or upcase to force them to be the same.

 

if "&missionNum." = "MISSION1" then

View solution in original post

14 REPLIES 14
PaigeMiller
Diamond | Level 26

Macros perform text substitution. The macro variable is replaced by the value of the macro variable when SAS runs.

 

So your code

 

if &MissionNum = 'MISSION1' then DO;

when you execute the code, simple text substition happens and it turns into this:

 

if MISSION1 = 'MISSION1' then DO;

Is that what you want? What do you want?

 

Advice ... get the code to work properly without macro variables for one instance of your problem. Once that is working without macro variables, it shouldn't be too hard to get it to work with macro variables.

--
Paige Miller
AMSAS
SAS Super FREQ
When developing macro code, it is always helpful to turn on the options SYMBOLGEN MPRINT & MLOGIC
BTAinRVA
Quartz | Level 8

AMSAS,

 

Thanks for the reply! I have turned on those options but there are no error messages. I see that

"Macro variable MISSIONNUM resolves to MISSION1". Apparently the program then looks for a variable in the data table named MISSION1 to see if it is equal to MISSION1. But as there is no variable named MISSION1 in the data table it creates one that simply has null values. What I want the program to do is evaluate if the variable MISSIONNUM = "MISSION1".

Tom
Super User Tom
Super User

@BTAinRVA wrote:

AMSAS,

 

Thanks for the reply! I have turned on those options but there are no error messages. I see that

"Macro variable MISSIONNUM resolves to MISSION1". Apparently the program then looks for a variable in the data table named MISSION1 to see if it is equal to MISSION1. But as there is no variable named MISSION1 in the data table it creates one that simply has null values. What I want the program to do is evaluate if the variable MISSIONNUM = "MISSION1".


No, That would just cause SAS to create a variable named MISSIONNUM instead of a variable named MISSION1.

To compare the value of the MISSIONNUM macro variable to a constant then have your macro generate SAS syntax that also looks like a constant.

if "&missionnum" = 'MISSION1' then ....

You can also use the SYMGET() function to return the value of a macro variable at run time.

if symget('missionnum') = 'MISSION1' then ....

Do you want the macro to conditionally generate code? 

If so then you need to use macro logic (%IF/%THEN/%DO/%END) instead of data step logic.

AMSAS
SAS Super FREQ

Sorry, I should have been clearer. Those options don't show errors. What they do is, show how the macros are being resolved. Hence as, you noted, you see &MISSIONNUM resolved to MISSION1, which is a variable that doesn't exist.

At Paige mentioned you are best to start without macros then slowly add them into the code

What I think you are trying to achieve is this:

 

if missionNum = "MISSION1" then do ;

  /* mission 1 logic goes here */

end ;

if missionNum = "MISSION2" then do ;

  /* mission 2 logic goes here */

end ;

if missionNum = "MISSION3" then do ;

  /* mission 3 logic goes here */

end ;

 

To do that you are going to need to use a macro and macro variables 

Take a look at the documentation Macro Variables and Using Macros

ballardw
Super User

@BTAinRVA wrote:

AMSAS,

 

Thanks for the reply! I have turned on those options but there are no error messages. I see that

"Macro variable MISSIONNUM resolves to MISSION1". Apparently the program then looks for a variable in the data table named MISSION1 to see if it is equal to MISSION1. But as there is no variable named MISSION1 in the data table it creates one that simply has null values. What I want the program to do is evaluate if the variable MISSIONNUM = "MISSION1".


This

%Let MissionNum = MISSION1;

Should be

%Let MissionNum = MISSIONNUM;

if you want the generated code for

if &MissionNum = 'MISSION1' then DO;

 

to resolve to

MISSIONNUM = "MISSION1 then do;

 

Any text that appears in the likely place of a variable name that does not generate an actual syntax error will have SAS place a variable with missing values (until possibly you assign them).

BTAinRVA
Quartz | Level 8

Paige,

 

Thanks for the reply! What I want it to do is evaluate the MissionNum variable to see if it is equal to MISSION1 , MISSION2, MISSION3, etc. so I can set some before & after date ranges. I don't want it to look for the value of a MISSION1 variable in the data table as there isn't one.

 

Thanks,

Brian

 

P.S. Are you the Paige Miller who worked for Kodak? 

Reeza
Super User

Be careful with your terminology with variable vs macro variable. 

 


@BTAinRVA wrote:

What I want it to do is evaluate the MissionNum variable to see if it is equal to MISSION1 , MISSION2, MISSION3, etc. s


 

I think you mean that you want to check if the value stored in the macro variable MissionNum is equal to MISSION1?

 

If so, this will work, but note the comparison is case sensitive. If you want it to be case insensitive, wrap it in lowcase or upcase to force them to be the same.

 

if "&missionNum." = "MISSION1" then
BTAinRVA
Quartz | Level 8

Reeza,

 

That seems to be working! However for some reason it is not flagging the Before & After periods. There are no errors in the log so I don't know why.

 

%Let DMISID = 0091;

%Let MissionNum = MISSION1;

 

 

data test;

set twenthrappntfin;

length Period $6.;

informat Period $6. ;

format Period $6. ;

 

if DMISID= &DMISID;

 

if '&MissionNum.' = 'MISSION1' then DO;

   if fm in (7 8 9 10 11 12) and fy= 2012 then do;

      Period = 'Before' ;

   end;

   else if fm in (2 3 4 5 6 7) and fy= 2013 then do;

      Period='After';

   end;

END;

 

if '&MissionNum.' = 'MISSION2' then DO;

    if (fm= 12 and fy= 2014) or (fm in (1 2 3 4 5) and fy= 2015) then do;

       Period = "Before";

    end;

    else if fm in (1 2 3 4 5 6) and fy= 2016 then do;

       Period = "After" ;

    end;

END;

 

 

Any help greatly appreciated!

BTAinRVA
Quartz | Level 8

Reeza,

 

I replaces the single quotes with double quotes and it's working now. Thanks much for your help!

 

And thanks to everyone who responded!

PaigeMiller
Diamond | Level 26

@BTAinRVA wrote:

Paige,

 

Thanks for the reply! What I want it to do is evaluate the MissionNum variable to see if it is equal to MISSION1 , MISSION2, MISSION3, etc. so I can set some before & after date ranges. I don't want it to look for the value of a MISSION1 variable in the data table as there isn't one.



It looks like you have your answer, but I point out that as I said above, you need to get your code working on a single instance WITHOUT MACRO variables, and then your process of turning this into code using macro variables will be much simpler. As far as the above explanation goes, I don't really know what you mean, but if you had showed actual working code for one instance without macros, it would be much clearer what you want.

--
Paige Miller
BTAinRVA
Quartz | Level 8

Paige,

 

I did have a working non-macro solution however I failed to save a copy of it before trying to transform it into a macro. I will definitely do that in the future. Thanks again for your guidance!

 

Brian

 

Tom
Super User Tom
Super User

Think about what SAS code you want your macro to generate.

Do you see the differences between the conditions in these statements?

if DMISID= 0091 then ...
if DMISID= 91 then ...
if DMISID= "0091" then ...

if Mission1 = 'MISSION1' then ...
if "Mission1" = 'MISSION1' then ...
if "MISSION1" = 'MISSION1' then ...
if MISSIONNUM = "MISSION1" then ...

Which of these forms is the proper SAS code that you would like your macro to generate for SAS to execute?

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
  • 14 replies
  • 1711 views
  • 6 likes
  • 7 in conversation