Better Workday Function - Workday2 Help

Joined
Feb 25, 2013
Messages
10
Hello all

I'm looking for assistance with Chip Pearson's Workday2 function, linked below;

Better Workday

Workday2 is a great alternate for Workday.INTL for those of us with Excel 2007.

My only issue is Workday2 does not allow 'DaysRequired' to be a negative integer. Allowing a negative integer would mean I could not only add specified work days to a date, but also minus specified work days from a date!

Unfortunately I am not great with VBA and i'm not sure if it's something that is even possible. But if someone with VBA experience could maybe offer some insight into whether allowing negative integers in this function is possible that would be great!

All input is greatly appreciated

Thank you in advance
 

Excel Facts

Bring active cell back into view
Start at A1 and select to A9999 while writing a formula, you can't see A1 anymore. Press Ctrl+Backspace to bring active cell into view.
It is not always easy to "get into" someone else's code, so you will need to test this code out several times (with and without a holiday list) to see if it actually returns the values you expect (please report back either way... if it works or it doesn't work), but I think it may now work in both directions (add or substract days depending on if the DaysRequired is a positive or negative value). Also note I changed the name of the macro to Workday3...
Code:
' EDaysOfWeek
' Days of the week to exclude. This is a bit-field
' enum, so that its values can be added or OR'd
' together to specify more than one day. E.g,.
' to exclude Tuesday and Saturday, use
' (Tuesday+Saturday), or (Tuesday OR Saturday)
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Enum EDaysOfWeek
    Sunday = 1      ' 2 ^ (vbSunday - 1)
    Monday = 2      ' 2 ^ (vbMonday - 1)
    Tuesday = 4     ' 2 ^ (vbTuesday - 1)
    Wednesday = 8   ' 2 ^ (vbWednesday - 1)
    Thursday = 16   ' 2 ^ (vbThursday - 1)
    Friday = 32     ' 2 ^ (vbFriday - 1)
    Saturday = 64   ' 2 ^ (vbSaturday - 1)
End Enum

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Workday3
' This is a replacement for the ATP WORKDAY function. It
' expands on WORKDAY by allowing you to specify any number
' of days of the week to exclude.
'   StartDate       The date on which the period starts.
'   DaysRequired    The number of workdays to include
'                   in the period.
'   ExcludeDOW      The sum of the values in EDaysOfWeek
'                   to exclude. E..g, to exclude Tuesday
'                   and Saturday, pass Tuesday+Saturday in
'                   this parameter.
'   Holidays        an array or range of dates to exclude
'                   from the period.
' RESULT:           A date that is DaysRequired past
'                   StartDate, excluding holidays and
'                   excluded days of the week.
' Because it is possible that combinations of holidays and
' excluded days of the week could make an end date impossible
' to determine (e.g., exclude all days of the week), the latest
' date that will be calculated is StartDate + (10 * DaysRequired).
' This limit is controlled by the RunawayLoopControl variable.
' If DaysRequired is less than zero, the result is #VALUE. If
' the RunawayLoopControl value is exceeded, the result is #VALUE.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function Workday3(StartDate As Date, DaysRequired As Long, _
                          ExcludeDOW As EDaysOfWeek, _
                          Optional Holidays As Variant) As Variant
    Dim N As Long ' generic counter
    Dim C As Long ' days actually worked
    Dim TestDate As Date ' incrementing date
    Dim HNdx As Long ' holidays index
    Dim CurDOW As EDaysOfWeek ' day of week of TestDate
    Dim IsHoliday As Boolean ' is TestDate a holiday?
    Dim RunawayLoopControl As Long ' prevent infinite looping
    Dim V As Variant    ' For Each loop variable for Holidays.
    
    If DaysRequired = 0 Then
        Workday3 = StartDate
        Exit Function
    End If
    
    If ExcludeDOW >= (Sunday + Monday + Tuesday + Wednesday + _
                Thursday + Friday + Saturday) Then
        ' all days of week excluded. get out with error.
        Workday3 = CVErr(xlErrValue)
        Exit Function
    End If
    
    ' this prevents an infinite loop which is possible
    ' under certain circumstances.
    RunawayLoopControl = DaysRequired * 10000
    N = 0
    C = 0
    ' loop until the number of actual days worked (C)
    ' is equal to the specified DaysRequired.
    Do Until C = DaysRequired
        N = N + Sgn(DaysRequired)
        TestDate = StartDate + N
        CurDOW = 2 ^ (Weekday(TestDate) - 1)
        If (CurDOW And ExcludeDOW) = 0 Then
            ' not excluded day of week. continue.
            IsHoliday = False
            ' test for holidays
            If IsMissing(Holidays) = False Then
                For Each V In Holidays
                    If V = TestDate Then
                        IsHoliday = True
                        ' TestDate is a holiday. get out and
                        ' don't count it.
                        Exit For
                    End If
                Next V
            End If
            If IsHoliday = False Then
                ' TestDate is not a holiday. Include the date.
                C = C + Sgn(DaysRequired)
            End If
        End If
        If Abs(N) > Abs(RunawayLoopControl) Then
            ' out of control loop. get out with #VALUE
            Workday3 = CVErr(xlErrValue)
            Exit Function
        End If
    Loop
    ' return the result
    Workday3 = StartDate + N
End Function
 
Upvote 0
I think I could do that create an if DaysRequired < 0 and then copy all the code in there and change some lines
Count days backwords TestDate = StartDate - N
C = C -1
At the end Workday2 = StartDate - N
I hope it helps
Sergio
 
Upvote 0
Rick

It works! It adds and minuses days, excluding specified days. You are a genius.

This is the only solid alternative to workday.intl for excel 2007 users I have come across. I hope others in my position are able to find this thread!

I didn't have to alter any of your Workday3 code, it behaved exactly as it should!

For future readers, an explanation for how this code can be put to use is found here: Better Workday

But ensure you adopt Rick's alternate if you wish to allow for a negative number of days.

Sergio, thank you for you input also!

Rick, thank you again for following up on my questions!

Amazing forum
 
Upvote 0
Hi,
I've tried both the Workday2 & Workday 3 functions trying to exclude Friday, Saturday & Sundays from workdays.
Both Workday2 & Workday3 returns a date on one of my excluded days.
Example:
=Workday2(date(2014,11,15),0,(32 + 64 + 1),Holidays)
Startdate is 15/11/2014 if this is a Friday, Saturday or Sunday as in my original post i need it to select the earlier Thursday.
The Workday2 function returned 15/11/2014.
The Workday3 function returned 15/11/2014.

Any ideas appreciated..
 
Upvote 0

Forum statistics

Threads
1,214,908
Messages
6,122,187
Members
449,072
Latest member
DW Draft

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top