Been there, done that. Here is a module that contains a function called WorkHours. You can use this as a formula in a cell.
WorkHours(StartDate As Date, NumHours As Double, StartShift As Date, EndShift As Date, Optional Holidays As Range)
StartDate is the date and time of the start of the project.
NumHours is the number of hours estimated for the project
StartShift is the time of day for shift start
EndShift is the time of day for shift end.
Holidays is an optional range containing the dates of holidays.
The result is a date and time when the project will be completed and this should be within working hours.
Function WorkHours(StartDate As Date, NumHours As Double, StartShift As Date, EndShift As Date, _
Optional Holidays As Range) As Date
Dim StartDay As Date ' Start of the workday
Dim EndDay As Date ' End of the workday
Dim EndTime As Date ' Ending time of project
Dim EndDate As Date ' Ending date of project
' Intitalize variables
EndTime = StartDate + NumHours / 24
EndDate = Int(StartDate)
StartDay = EndDate + StartShift
EndDay = EndDate + EndShift
' Calculate whole days
While EndTime > EndDay ' while the end time exceeds end of current day
If IsWorkday(StartDay, Holidays) = False Then
' If it is a weekday or holiday, push the days and due day up by a day and do nothing else
StartDay = StartDay + 1
EndDay = EndDay + 1
EndTime = EndTime + 1
Else
' If it is a workday, push the day up, but keep due the same
EndDay = EndDay + 1
If NumHours > 24 * (EndShift - StartShift) Then
' If you need more hours than is in a day, decrement the hours and push up the start date
NumHours = NumHours - 24 * (EndShift - StartShift)
StartDay = StartDay + 1
End If
If IsWorkday(StartDay, Holidays) = False And NumHours > (EndShift - StartShift) Then
EndTime = EndTime + 1
End If
End If
Wend
WorkHours = StartDay + NumHours / 24
End Function
Function IsWorkday(MyDate As Date, Optional Holidays As Range) As Boolean
Dim cl As Range
Dim bRtn As Boolean
Dim WkDay As Long
bRtn = True
If Not Holidays Is Nothing Then
For Each cl In Holidays
If Int(MyDate) = cl.Value Then
bRtn = False
Exit For
End If
Next
End If
WkDay = Weekday(MyDate, vbMonday)
If WkDay > 5 Then
bRtn = False
End If
IsWorkday = bRtn
End Function
Bookmarks