Date: Thu, 9 Oct 2008 20:40:34 +0000
Reply-To: iw1junk@COMCAST.NET
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ian Whitlock <iw1junk@COMCAST.NET>
Subject: Re: calculate last day to start vacation
Summary: calculate last day to start vacation or loose time
#iw-value=1
gbb wanted to calculate when a vacation must start to use up vacation
hours by the end of the year. The work week is of three different
types held in a variable SCHEDULE.
> * schedule 1 = Mo-Fr, 2=Tu-Sa, 3=Sa,Su, Mo-We ;
If vacation hours become reasonable then holidays may also need
exclusion.
Here is sample code with some debugging code.
data temp;
input schedule hours; * schedule 1 = Mo-Fr, 2=Tu-Sa, 3=Sa,Su, Mo-
We ;
cards ;
1 16
2 50
3 80
;
proc format ;
value holiday
"27nov2008"d , "25dec2008"d = "1"
other = "0"
;
run ;
data w ( keep = shedule hours start enddate ) ;
/* 1: 2,3,4,5,6 mod( ,7) 2-6
2: 3,4,5,6,7 mod( ,7) 3-6, 0
3 :7,1,2,3,4 mod( ,7) 0-4
*/
array ok (3,7) _temporary_ ( 0 1 1 1 1 1 0
0 0 1 1 1 1 1
1 1 1 1 1 0 0 ) ;
*enddate = intnx("year" , today(), 0, "e") ;
set temp ;
/* choose some enddates - op had 31dec<year> */
do enddate = "1nov2008"d to "31dec2008"d by 8 ;
/* get date that vacation must start or lose time */
cnt = 0;
do dt = enddate by -1 until ( cnt >= ceil(hours/8) ) ;
weekday = weekday(dt) ;
cnt + (ok[schedule,weekday(dt)] and put (dt, holiday1.) =
"0") ;
end ;
start = dt ;
output ;
/* show result */
put schedule= hours= start= date9. enddate= date9.;
/* show some details including holidays */
if start in ( "19nov2008"d "11dec2008"d ) then
do ;
do dt = start to enddate ;
weekday = weekday(dt) ;
x = ok[schedule,weekday(dt)] ;
y = (put(dt, holiday1.) = "0" ) ;
put schedule= hours= dt = date9. weekday= +2 x= y= ;
end ;
end ;
end ;
run ;
The code is probably not the most efficient, since it requires
counting days when tests are passed for each employee, but it is
probably the easiest to write and understand. If there are many
employees with various hours say ranging from 8 to 160 hours then it
might pay to do the calculations once for each schedule/hour and put
the result in an informat, say GETDATE, mapping.
catx("_", enddate, schedule, hours) ==> start
Then code reuduces to
start = input ( catx("_", enddate, schedule, hours), getdate. ) ;
To make the informat, use code similar to the above looping through
all combinations of interest and read about the CNTLIN option of PROC
FORMAT. You may need to make a small informat by hand and use CNLOUT
option to get all the relevant variables since the documentation
leaves much for user exploration.
Ian Whitlock
|