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

Hi All,

 

I am having an error when trying to run this code:

 

%let bcfdate = today();

%let days = 8;

 

data _null_;

%let bcfstart=%sysfunc(intnx("day",%sysfunc(&bcfdate.),-&days.));

run;

%put &bcfstart.;

 

I believe that the today() function cannot be processed in the data _null_ statement and therefore "bcfstart" cannot be calculated

 

Does anyone have any ideas on how to get around this issue?

Cheers.

1 ACCEPTED SOLUTION

Accepted Solutions
PeterClemmensen
Tourmaline | Level 20

I believe this is what you want and a bit simpler

 

%let days = 8;

data _null_;
	format bcfstart date9.;
	bcfstart=intnx("day",today(),-&days.);
	put bcfstart;
run;


View solution in original post

9 REPLIES 9
LinusH
Tourmaline | Level 20

Why are you storing today() in a macro variable?

If this is the first thing that happens in your session, use "&Sysdate"d instead.

Also, %sysfunc should be used in open code, not within a data step.

Please look at more examples on how to use %sysfunc, intnx, today() etc.

Data never sleeps
PeterClemmensen
Tourmaline | Level 20

I believe this is what you want and a bit simpler

 

%let days = 8;

data _null_;
	format bcfstart date9.;
	bcfstart=intnx("day",today(),-&days.);
	put bcfstart;
run;


Kurt_Bremser
Super User

A macro statement is resolved before the other SAS code is interpreted. So the data step ends up as

data _null_;
run;

which is, of course, totally useless.

So let's look at the macro statement that you wrote into the data step code (not into the data step, mind!).

After resolution of the two macro variables, we get

%let bcfstart=%sysfunc(intnx("day",%sysfunc(today()),-8));

Note that you wrote "day", not day without quotes. The macro processor knows only one datatype, text, and therefore does not need quotes around strings. If quotes are used, they become part of the string, so what is fed to the datastep function within the %sysfunc will appear as

intnx('"day"',

which is invalid syntax and gets you a

WARNING: Argument 1 to function INTNX referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.

which basically says it all.

Maxim 2: Read the LOG.

 

If you want to do your calculation in a data step (for easier reading), do this:

%let bcfdate = %sysfunc(today());
%let days = 8;

data _null_;
bcfstart = intnx("day",&bcfdate.,-&days.);
call symput('bcfstart',put(bcfstart,best.));
run;

%put &bcfstart.;

You will see that &bcfstart now contains the raw value for the intended date, which is perfectly fine for date calculations later in the code.

PriyaL
Fluorite | Level 6

Thanks for your solution.

 

Is this a local macro variable?

 

It is just that I need to use this in a title as follows:

 

title3 "Date range &bcfstart to &bcfend";

 

And SAS does not seem to pick up these macros.

Thanks.

Quentin
Super User

You may not need macro variables at all.  Some folks feel pure macro code can be hard to read.  But I don't mind it.

 

You can code:

101  %put %sysfunc(intnx(day,%sysfunc(today()),-8),mmddyy10);
05/15/2017
102  %put %sysfunc(intnx(day,%sysfunc(today()),8),mmddyy10);
05/31/2017

 

If you want macro variables for bcfdate and day, just make sure bcfdate is assigned a SAS date value, e.g.:

103  %let bcfdate=%sysfunc(today());
104  %let days=8;
105  %put %sysfunc(intnx(day,&bcfdate,-&days),mmddyy10);
05/15/2017
106  %put %sysfunc(intnx(day,&bcfdate,&days),mmddyy10);
05/31/2017

You can use that in a title statement as well:

 

title3 "Date range %sysfunc(intnx(day,&bcfdate,-&days),mmddyy10) to %sysfunc(intnx(day,&bcfdate,&days),mmddyy10)";

 

And if you really wanted to, you could make a little macro function to do the work for you.  Some would say that is overkill.  But if you need to create relative dates often, it might make sense.  Peter Crawford has a great paper on a %now macro:

http://www2.sas.com/proceedings/sugi31/038-31.pdf

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
RW9
Diamond | Level 26 RW9
Diamond | Level 26

 

data _null_;
  call execute(cat('title3 "Date range ',put(date(),date9.),' to ',put(date()+8,date9.),'";'));
run;

Or if you really want to use macro variables:

data _null_;
  call symputx('title',(cat('title3 "Date range ',put(date(),date9.),' to ',put(date()+8,date9.),'";')));
run;

 

 

Kurt_Bremser
Super User

@PriyaL wrote:

Thanks for your solution.

 

Is this a local macro variable?

 

It is just that I need to use this in a title as follows:

 

title3 "Date range &bcfstart to &bcfend";

 

And SAS does not seem to pick up these macros.

Thanks.


Any macro variable created inside a macro will be in the local macro table and vanish after the macro has executed. Only variables that already existed in the global table, or were created with call symputx and the 'g' option, or named in a %global statement will be global.

 

So it depends on where you create the macro variables.

Tom
Super User Tom
Super User

If you used the code in the answered that is marked as correct there is no macro variable created by that code. You could add a CALL SYMPUTX() statement to make one if you want.  

 

Note that SAS dates are number of days. So no need to use the INTNX() function to add/subtract days.

You can use the automatic macro variable SYSDATE9 which should have the date the SAS session started in DATE9 format.  If you have long running sessions that could span multiple days and you really need the date that this block of code started then you could use the DATE() function (or it's alias the TODAY() function).

%let bcfend = &sysdate9;
%let days = 8;
data _null_;
  call symputx('bcfstart',put("&bcfend"d - &days,date9.));
run;
title3 "Date range &bcfstart to &bcfend";

 If you are running inside of a macro that is ended before your TITLE statement runs then you might need to add the optional third parameter to make sure it generates a GLOBAL macro variable.  Without that if the macro variable does not already exist then CALL SYMPUTX() will make it in the symbol table for the macro and it will disappear when the macro finishes running.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Doesn't make sense on several levels.  First today() is a base SAS function you can use anywhere, creating a macro variable doesn't make sense here as you can just replace that macro variable with today().  A simple way of doing this is:

data _null_;
  call symputx('bcfstart',today()+8;
run;

Although there really isn't a point in that either as you can just put: today()+8 anywhere you need it for the same effect - i.e. creating code for no reason.

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
  • 9 replies
  • 2835 views
  • 2 likes
  • 7 in conversation