BookmarkSubscribeRSS Feed
nickspencer
Obsidian | Level 7
Hi,
I have this SAS program which is supposed to be run monthly on the first weekday of the month. It has been scheduled to run daily through cron.
Is there a way I can wrap this program in a macro that will execute only if it is the first weekday of the month otherwise will exit. Also to account for public/business holidays I have a calendar dataset which looks like this.
Date Bus_ind Day_cd
1/1/2018 0 New Year’s Day
1/2/2018 1 Workday
1/3/2018 1 Workday
1/4/2018 1 Workday
1/5/2018 1 Workday
1/6/2018 0 Weekend


Any suggestions or code example is highly appreciated.

Thanks
6 REPLIES 6
ChrisNZ
Tourmaline | Level 20
If I were you, I'd include one-byte Boolean fields in your calendar table, like 
Business day 
Week-end day 
Holiday day 
First calendar day of the calendar year 
First calendar day of the fiscal year 
First calendar day of the quarter 
First calendar day of the month 
First calendar day of the week 
First business day of the quarter 
First business day of the month 
First business day of the week 
Second calendar day of the quarter 
Second calendar day of the month 
Second calendar day of the week 
Second business day of the quarter 
Second business day of the month 
Second business day of the week 
Last calendar day of the quarter 
Last calendar day of the month 
Last calendar day of the week 
Last business day of the quarter 
Last business day of the month 
Last business day of the week 
etc 
This would make scheduling anything at all very easy. 
Alternatively, you could store these as formats and apply the format on the date.
RW9
Diamond | Level 26 RW9
Diamond | Level 26

If you have a scheduler setup to run the program at a given moment, why are you then running it all the time and coding in a check to only run it at a certain timepoint?  That is the purpose of the scheduler, so fix the scheduler to run the code only when you want to.

FredrikE
Rhodochrosite | Level 12

Hi!

I agree with @RW9, but sometimes you really want to make sure the program is not run on wrong dates.

 

This code checks if today is runday. If you have another variable telling which day you are running, just change today() to that variable 🙂

 

Think this small example will work:

 

data dates;
 length Date Bus_ind 8 ;
 format date yymmdd10.;
 informat date anydtdte.;
 input date bus_ind;
 datalines;
1/1/2018 0 New Years Day
1/2/2018 1 Workday
1/3/2018 1 Workday
1/4/2018 1 Workday
1/5/2018 1 Workday
1/6/2018 0 Weekend
20/8/2018 1 Test
;
run;

%let runnow = 0;


data runnow;
 set dates;
 where date = today();
 if bus_ind then run = 1;
 else run = 0;
 call symput('runnow',run);
run;

%put &runnow;

%if &runnow %then %do;
 %put *** Job execution day! ***;
/* code that should be executed */
%end;
%else %do;
 %put *** Job will not run today since it is not marked to do so in the calender :) ! ***;
%end;

//Fredrik

Criptic
Lapis Lazuli | Level 10

First not considering holidays - you could built on that to get more automation. So if it is a holiday add + 1 to the current date and if it is not a saturday or sunday then execute:

 

data _NULL_;
 firstOfMonth =  intnx('month', date(), 0);
 dayOfWeek = weekday(firstOfMonth);
 * Sunday;
 if dayOfWeek = 1 then firstWorkDay = firstOfMonth + 1;
 * Saturday;
 else if dayOfWeek = 2 then firstWorkDay = firstofMonth + 2;
 else firstWorkDay = firstOfMonth;
 if date() eq firstOfMonth then
	do;
		put "Macro Execution";
	end;
 else put "Not first busisnessday";
run;

If you are already creating a table why not just create one which has the date of the first businessday for each month and then just check against that table. Let's say that table as the column date_firstBusinessDay which contains the SAS date value for the first business day for each month. Sure you would have to redo this table each year with the new values but getting around holidays is not an easy task.

data _null_;
 set businessDayTable;
 if date_firstBusinessDay eq date() then
	do;
		put "Macro Execution";
	end;
 else put "Not first business day";
run;

Hope this helps

s_lassen
Meteorite | Level 14

One possibility is to extract the run dates from your calendar, like this:

Data rundates(index=(date));
  set calendar;
  where bus_ind=1;
  if month(date) ne month(lag(date));
  keep date;
run;

Then, in the top of your batch program put a datastep like this;

data _null_;
  date=today();
  set rundates key=date;
  if _iorc_ then do;
    put 'Today is not first business day of month, aborting';
    _error_=0;
    abort return 0;
    end;
run;

Of course, you will want to store you rundates table in a permanent library.

Ksharp
Super User

data want;

 set have;

 year=year(date);

 month=month(date);

 if  date=nwkdom(1, 2, month, year) then output;

run;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 4009 views
  • 2 likes
  • 7 in conversation