data _null_;
call symput ('firstday', intnx('month',today()-1,0,'B'));
call symput ('lastday',intnx('month',today()-1,0,'E'));
run;
%put &firstday &lastday;
This works fine in EG 5.1, but when I ran the program that uses this as a batch process, somehow the firstday and lastday are not resolving. What would be the issue here?
Is there any other code that could be used to create firstday and lastday of the month going forward that would work in Linux crontab?
Thanks much.
The problem is that you are executing the %GLOBAL statement conditionally inside of just one branch of your %IF/%THEN loops. So when it is not executed then FIRSTDAY is defined as LOCAL and so does not exist after the macro exits.
Why would you use a macro for this problem? What is your conditional logic doing anyway? There is no need to subtract an extra day for the first of the month. Subtracting one day should be enough to make the range be for the previous month when it is the first day of the month.
data _null_;
today = today();
firstday = intnx('month',today -1,0,'b');
lastday = intnx('month',today -1,0,'e');
put (today firstday lastday) (= date9.) ;
call symputx('firstday',firstday);
call symputx('lastday',lastday);
run;
%put &firstday &lastday;
If you print out the value for the today function in batch mode what do you get? You could add these lines to the data _null_ step.
x= today();
put x mmddyy10.;
There is nothing wrong with that code.
Perhaps you have embedded this into a larger program that is causing your actual problem? Can you past example from your SAS log?
For example if you ran the CALL SYMPUT() statements inside of a macro and had not either previously create the macro variables or defined them as global then once the macro finished the local macro variables would disappear.
todayminus1= 4
MPRINT(FIRSTDAYOFMONTH): data _null_;
MPRINT(FIRSTDAYOFMONTH): call symput ('firstday', intnx('month',today()-1,0,'B'));
MPRINT(FIRSTDAYOFMONTH): call symput ('lastday', intnx('month',today()-1,0,'E'));
MPRINT(FIRSTDAYOFMONTH): run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
153:45 153:106
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds
4 The SAS System 12:00 Friday, September 4, 2015
WARNING: Apparent symbolic reference FIRSTDAY not resolved.
WARNING: Apparent symbolic reference LASTDAY not resolved.
&firstday &lastday
I changed the code little bit like this:
/*Find the day of the month using this macro*/
data _null_;
call symput ('todayminus1', day(today()));
run;
%put todayminus1=&todayminus1;
/*If the day of the month is first then we have to use the last month first day and last month last day for date calculations*/
%macro FirstDayOfMonth;
%IF (&todayminus1. = 1) %THEN
%DO;
%global firstday lastday;
data _null_;
call symput ('firstday', intnx('month',today()-2,0,'B'));
call symput ('lastday',intnx('month',today()-2,0,'E'));
%let today = today();
run;
%END;
%IF (&todayminus1. ^= 1) %THEN
%DO;
data _null_;
call symput ('firstday', intnx('month',today()-1,0,'B'));
call symput ('lastday', intnx('month',today()-1,0,'E'));
%let today = today();
run;
%END;
%mend FirstDayOfMonth;
%FirstDayOfMonth;
%put &firstday &lastday;
But still not able to resolve the days, here is the log:
14 /*Find the day of the month using this macro*/
15 data _null_;
16 call symput ('todayminus1', day(today()));
17 run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
16:30
NOTE: DATA statement used (Total process time):
real time 0.10 seconds
cpu time 0.02 seconds
2 The SAS System 15:35 Thursday, September 17, 2015
SYMBOLGEN: Macro variable TODAYMINUS1 resolves to 17
18 %put todayminus1=&todayminus1;
todayminus1= 17
19
20 /*If the day of the month is first then we have to use the last month first day and last month last day for date
20 ! calculations*/
21 %macro FirstDayOfMonth;
22 %IF (&todayminus1. = 1) %THEN
23 %DO;
24 %global firstday lastday;
25 data _null_;
26 call symput ('firstday', intnx('month',today()-4,0,'Beginning'));
27 call symput ('lastday',intnx('month',today()-4,0,'Ending'));
28 %let today = today();
29 run;
30 %END;
31
32 %IF (&todayminus1. ^= 1) %THEN
33 %DO;
34 data _null_;
35 call symput ('firstday', intnx('month',today()-1,0,'Beginning'));
36 call symput ('lastday', intnx('month',today()-1,0,'Ending'));
37 %let today = today();
38 run;
39
40 %END;
41 %mend FirstDayOfMonth;
42
43 %FirstDayOfMonth;
SYMBOLGEN: Macro variable TODAYMINUS1 resolves to 17
SYMBOLGEN: Macro variable TODAYMINUS1 resolves to 17
MPRINT(FIRSTDAYOFMONTH): data _null_;
MPRINT(FIRSTDAYOFMONTH): call symput ('firstday', intnx('month',today()-1,0,'Beginning'));
MPRINT(FIRSTDAYOFMONTH): call symput ('lastday', intnx('month',today()-1,0,'Ending'));
MPRINT(FIRSTDAYOFMONTH): run;
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
43:45 43:114
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds
WARNING: Apparent symbolic reference FIRSTDAY not resolved.
WARNING: Apparent symbolic reference LASTDAY not resolved.
44
45 %put &firstday &lastday;
&firstday &lastday
The problem is that you are executing the %GLOBAL statement conditionally inside of just one branch of your %IF/%THEN loops. So when it is not executed then FIRSTDAY is defined as LOCAL and so does not exist after the macro exits.
Why would you use a macro for this problem? What is your conditional logic doing anyway? There is no need to subtract an extra day for the first of the month. Subtracting one day should be enough to make the range be for the previous month when it is the first day of the month.
data _null_;
today = today();
firstday = intnx('month',today -1,0,'b');
lastday = intnx('month',today -1,0,'e');
put (today firstday lastday) (= date9.) ;
call symputx('firstday',firstday);
call symputx('lastday',lastday);
run;
%put &firstday &lastday;
Thanks a lot Tom, this is useful.
I will follow simple version like this one next time.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.