View Full Version : Exclude holiday from working days
Hi all,
I have tried to exclude weekends from the working days. Shown below is the code. My problem is how to exclude holidays also.. If the holiday falls on sunday, monday is also a public holiday.. http://vbaexpress.com/forum/images/smilies/banghead.gif
Thanks a lot..
Function Work_Days(BegDate As Variant, EndDate As Variant) As Integer
Dim WholeWeeks As Variant
Dim DateCnt As Variant
Dim EndDays As Integer
On Error GoTo Err_Work_Days
Set DB = CurrentDb()
Set rs = DB.OpenRecordset("Holiday")
BegDate = DateValue(fStartDate)
EndDate = DateValue(fEndDate)
WholeWeeks = DateDiff("w", BegDate, EndDate)
DateCnt = DateAdd("ww", WholeWeeks, BegDate)
EndDays = 0
Do While DateCnt <= EndDate
If Format(DateCnt, "ddd") <> "Sun" And Format(DateCnt, "ddd") <> "Sat" Then
EndDays = EndDays + 1
End If
DateCnt = DateAdd("d", 1, DateCnt)
Loop
Work_Days = WholeWeeks * 5 + EndDays - 1
Exit Function
Err_Work_Days:
If Err.Number = 94 Then
Work_Days = 0
Exit Function
Else
If Err.Number = 13 Then
Work_Days = 0
Exit Function
End If
End If
End Function
XLGibbs
02-23-2006, 07:20 AM
There is a NetWorkDay function available..which has arguments fro date parameters and holidays....to which each argument can be multiple dates...
I believe it is part of the Analysis Toolpak Add In, which comes installed, you just have to check the box in Tools>Addins to see if it is checked off...
Whooops...my bad...thought this was an excel question...didn't see the whoe Recordset business.
XLGibbs
02-23-2006, 07:26 AM
It seems like you could just do a count of days minues the records in that range that appear in the Holidays recordset...
You calculate your datediff between beg/end and get the workdays okay, so you just need to take that number and subtract the COUNT of holiday dates that fall between beg and end date..
sqlHolidays = "Select Count(*) From [Holidays] Where Date between #" & BegDate & "# and #" & endDate & "#"
Which would give you a count of the holiday dates between begin and end dates passed... subtract that number from the other calculation....
perhaps?
matthewspatrick
02-23-2006, 08:19 AM
I use a UDF to calculate working hours between a start datetime and an end datetime, where I can define which weekdays are workdays and what the daily start and end working times are. You might want to try it out here:
Function WorkingHrs(StartAt As Date, EndAt As Date, WorkStart As Date, WorkEnd As Date, Workdays As String, _
ParamArray Holidays())
' Function calculates working hours available within a specified datetime range, allowing for
' scheduled working hours, non-working days, and holidays (if desired)
' Workdays specifies days employees normally work. For example, to use Mon - Fri, use 23456.
' To do just Tue & Thu, use 35; etc.
' assumes scheduled working hrs are the same on each working day!
Dim Counter As Long
Dim Dict As Object
Dim x As Variant
Dim Days(1 To 7) As Boolean
Dim WorkThisDay As Boolean
Dim HolThisDay As Boolean
Dim DateToday As Date
Dim DayStart As Date
Dim DayEnd As Date
' array indicates whether that weekday is a regular workday. Initialize to False
Days(1) = False
Days(2) = False
Days(3) = False
Days(4) = False
Days(5) = False
Days(6) = False
Days(7) = False
' populate array with results from Workdays argument
For Counter = 1 To Len(Workdays)
Days(Val(Mid(Workdays, Counter, 1))) = True
Next
On Error GoTo Cleanup
' populate holiday array
If Not IsMissing(Holidays) Then
Set Dict = CreateObject("Scripting.Dictionary")
For Each x In Holidays
If Not Dict.Exists(Format(x, "m/d/yyyy")) Then Dict.Add Format(x, "m/d/yyyy"), Format(x, "m/d/yyyy")
Next
End If
'loop through days in datetime range
For Counter = Int(StartAt) To Int(EndAt)
DateToday = CDate(Counter)
' determine if regular workday
WorkThisDay = Days(Weekday(DateToday, vbSunday))
' determine if holiday
If IsMissing(Holidays) Then
HolThisDay = False
Else
If Dict.Exists(Format(DateToday, "m/d/yyyy")) Then HolThisDay = True Else HolThisDay = False
End If
' if regular workday and not a holiday, figure out hrs from that day
If WorkThisDay And Not HolThisDay Then
' starts and ends on same day
If Int(StartAt) = Int(EndAt) Then
DayStart = IIf(CDate(StartAt - Int(StartAt)) > WorkStart, CDate(StartAt - Int(StartAt)), WorkStart)
DayEnd = IIf(CDate(EndAt - Int(EndAt)) < WorkEnd, CDate(EndAt - Int(EndAt)), WorkEnd)
WorkingHrs = IIf(CDbl(DayEnd - DayStart) < 0, 0, CDbl(DayEnd - DayStart))
' first day, if first day <> last day
ElseIf Counter = Int(StartAt) Then
DayStart = IIf(CDate(StartAt - Int(StartAt)) > WorkStart, CDate(StartAt - Int(StartAt)), WorkStart)
DayEnd = WorkEnd
WorkingHrs = IIf(CDbl(DayEnd - DayStart) < 0, 0, CDbl(DayEnd - DayStart))
' days in between start and end, if any
ElseIf Counter > Int(StartAt) And Counter < Int(EndAt) Then
WorkingHrs = WorkingHrs + CDbl(WorkEnd - WorkStart)
' last day, if first day <> last day
ElseIf Counter = Int(EndAt) Then
DayStart = IIf(CDate(EndAt - Int(EndAt)) > WorkStart, WorkStart, CDate(EndAt - Int(EndAt)))
DayEnd = IIf(CDate(EndAt - Int(EndAt)) < WorkEnd, CDate(EndAt - Int(EndAt)), WorkEnd)
WorkingHrs = WorkingHrs + IIf(CDbl(DayEnd - DayStart) < 0, 0, CDbl(DayEnd - DayStart))
End If
End If
Next
' convert days to hours
WorkingHrs = WorkingHrs * 24
Cleanup:
On Error GoTo 0
Set Dict = Nothing
End Function
To use it to calculate days:
WorkingHrs(Int([StartDateTime]), Int([EndDateTime]) + 1, 0, 1, 23456) / 24
You can supply additional arguments to specify holidays.
Patrick
It seems like you could just do a count of days minues the records in that range that appear in the Holidays recordset...
You calculate your datediff between beg/end and get the workdays okay, so you just need to take that number and subtract the COUNT of holiday dates that fall between beg and end date..
sqlHolidays = "Select Count(*) From [Holidays] Where Date between #" & BegDate & "# and #" & endDate & "#"
Which would give you a count of the holiday dates between begin and end dates passed... subtract that number from the other calculation....
perhaps?
So sorry how to i get the value from the sql statement? is there getInt() in vba? First time using vba.. So sorry..
XLGibbs
02-25-2006, 08:36 AM
It may be easier to use Patricks User Defined Function's and his sameple formula.
You can also just put a query in the database that looks at the holiday table and does a count of all records, and takes parameters for the days from your form perhaps.
Don't make it more complicated that it has to be.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.