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

Hi,

 

I need to do following and store result into a macro variable:

 

> extract month from a variable,

> add a constant

 

I have:

%let day_act = mdy(3,13,2018);

%let i = -1;

 

%let want2 = MONTH(&day_act.) + &i.; /*expect to return numeric 2*/

 

I have been googling for quite some time and tried several combinations of SYSFUNC, EVAL etc. without desired result.

 

___ BTW. I have come up with following solution:

DATA WORK.tmp;
want2 = MONTH(&day_act.) + &i.;
RUN;


DATA _NULL_;
SET WORK.tmp;
call symput('want2', want2);
RUN;
%put &want2.; /*It gives exactly what I want*/

 

 

BUT! Oddly, when trying to do this:

 

DATA WORK.rep_&want2.;
SET WORK.something;
RUN;

 

I receive bunch of blank spaces like 

WORK.rep_           2, which obviously gives me an error.

 

 

I would very much appreciate any advice how to reach my goal without DATA step and also I am curious what causes the later error with blank spaces.

 

Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
SuryaKiran
Meteorite | Level 14

You need to use %SYSFUNC() in day_act too.

 

%let day_act = %SYSFUNC(mdy(3,13,2018));
%put &day_act;
%let i = -1;
%put &i;
%let want2 = %EVAL(%SYSFUNC(MONTH(&day_act.)) + &i.); /*expect to return numeric 2*/
%put &want2;

Also you can try something like this:

%let want2 =%SYSFUNC(MONTH(%SYSFUNC(INTNX(MONTH,&day_act.,-1)))); /*expect to return numeric 2*/
Thanks,
Suryakiran

View solution in original post

5 REPLIES 5
LinusH
Tourmaline | Level 20

Your assignment should throgh a message about converting to char or something.

you should use put(month(),best.), and use the left() to remove preceding blanks..

left(put(month(&day_act. + &i.),best.)

 

Data never sleeps
Tom
Super User Tom
Super User

Unless you really want to store leading and/or trailing spaces into your macro variables you should NOT be using the older CALL SYMPUT() function.

 

Use the newer CALL SYMPUTX() which will automatically strip the leading and trailing spaces.

JamesBlack
Fluorite | Level 6

Thank you, guys.

 

Your suggestions are useful in combination with my DATA step solution, which is good.

 

I was expecting something simpler, though. When I run:

 

%let want2 = left(put(month(&day_act.) + &i.,best.));
%put &want2.;

 

I get the string 'left(put(month(mdy(3,13,2018)) + -1,best.))'. It's also useful in my code, but this time I would like to have '2' returned. I tried RESOLVE etc. If there were something like that, it would make the code much simpler.

ballardw
Super User

@JamesBlack wrote:

Thank you, guys.

 

Your suggestions are useful in combination with my DATA step solution, which is good.

 

I was expecting something simpler, though. When I run:

 

%let want2 = left(put(month(&day_act.) + &i.,best.));
%put &want2.;

 

I get the string 'left(put(month(mdy(3,13,2018)) + -1,best.))'. It's also useful in my code, but this time I would like to have '2' returned. I tried RESOLVE etc. If there were something like that, it would make the code much simpler.


If you want to actually execute a data step function such as Month in a macro assignment every single function used has to be enclosed in a %sysfunc() call. %SYSFUNC macro function tells the SAS compiler to use the data step function. Otherwise you get text.

Also the macro language doesn't "like" the put statement and wants Putn(variable, format.)

 

%let want2 = %sysfunc( left(%sysfunc (putn( %sysfunc(month(&day_act.)  ) + &i.,best.)) ) );

might work. Multiple function calls in statement gets very ugly quickly. Often I may be easier to use a data _null_ step and call symputx.

 

 

Note that there are a number of data step function that have macro equivalents such as Index/%index, Length/%Length, Scan /%scan

SuryaKiran
Meteorite | Level 14

You need to use %SYSFUNC() in day_act too.

 

%let day_act = %SYSFUNC(mdy(3,13,2018));
%put &day_act;
%let i = -1;
%put &i;
%let want2 = %EVAL(%SYSFUNC(MONTH(&day_act.)) + &i.); /*expect to return numeric 2*/
%put &want2;

Also you can try something like this:

%let want2 =%SYSFUNC(MONTH(%SYSFUNC(INTNX(MONTH,&day_act.,-1)))); /*expect to return numeric 2*/
Thanks,
Suryakiran

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
  • 5 replies
  • 2505 views
  • 2 likes
  • 5 in conversation