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.
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;
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.
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;
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.
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.
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
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;
@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.
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.
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 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.