Nth Occurrence in Date Order based on two columns
I am trying to lookup the date for the nth [e.g. 1st, 2nd, 3rd, 4th, Last] business day for a given month and currency.
e.g. the [1st, 2nd, 3rd, 4th, Last] "Business Day" for "PLN" in the month of January.
(The below dates may be wrong - here is the sample data)
DATE | CURRENCY | DAY TYPE |
---|---|---|
1/1/2022 | PLN | New Years Day |
1/2/2022 | PLN | Weekend |
1/3/2022 | PLN | Business Day |
1/4/2022 | PLN | Business Day |
1/5/2022 | PLN | Business Day |
1/6/2022 | PLN | Epiphany |
1/7/2022 | PLN | Business Day |
1/8/2022 | PLN | Weekend |
1/9/2022 | PLN | Weekend |
1/10/2022 | PLN | Business Day |
1/11/2022 | PLN | Business Day |
1/12/2022 | PLN | Business Day |
1/13/2022 | PLN | Business Day |
1/14/2022 | PLN | Business Day |
1/15/2022 | PLN | Weekend |
1/16/2022 | PLN | Weekend |
1/17/2022 | PLN | Business Day |
1/18/2022 | PLN | Business Day |
1/19/2022 | PLN | Business Day |
1/20/2022 | PLN | Business Day |
1/21/2022 | PLN | Business Day |
1/22/2022 | PLN | Weekend |
1/23/2022 | PLN | Weekend |
1/24/2022 | PLN | Business Day |
1/25/2022 | PLN | Business Day |
1/26/2022 | PLN | Business Day |
1/27/2022 | PLN | Business Day |
1/28/2022 | PLN | Business Day |
1/29/2022 | PLN | Weekend |
1/30/2022 | PLN | Weekend |
1/31/2022 | PLN | Business Day |
2/1/2022 | PLN | Business Day |
2/2/2022 | PLN | Business Day |
2/3/2022 | PLN | Business Day |
2/4/2022 | PLN | Business Day |
2/5/2022 | PLN | Weekend |
2/6/2022 | PLN | Weekend |
2/7/2022 | PLN | Business Day |
2/8/2022 | PLN | Business Day |
My attempt at creating a function to complete this:
Function NthBusinessDay(Nth As Variant, FcstCurrency As Variant, MonthNumber As Variant, YearNumber As Variant) As Variant
Dim varVal1 As Variant
Dim varVal2 As Variant
Dim varVal3 As Variant
Dim varVal4 As Variant
Dim rngTargetA As Range
Dim rngTargetB As Range
Dim lngRowCounter As Long
Dim ws As Worksheet
Dim wb As Workbook
varVal1 = FcstCurrency
varVal2 = MonthNumber
varVal3 = YearNumber
varVal4 = Nth
Set wb = ActiveWorkbook
Set ws = wb.Sheets("CCY_HOL_CAL(LIVE)")
lngRowCounter = 2
Set rngTargetA = ws.Range("B" & lngRowCounter)
Set rngTargetB = ws.Range("C" & lngRowCounter)
Do While Not IsEmpty(rngTargetA.Value)
If rngTargetA.Value = varVal1 And rngTargetB.Value = "Business Day" Then
FindValue = ws.Range("A" & lngRowCounter).Value
Exit Function
End If
lngRowCounter = lngRowCounter + 1
Set rngTargetA = ws.Range("B" & lngRowCounter)
Set rngTargetB = ws.Range("C" & lngRowCounter)
Loop
FindValue = "Nothing"
End Function
How do I make this function hold true for the nth day and the last day in a given month?
Expected results:
1st Business Day = 1/3/2022
2nd Business Day = 1/4/2022
3rd Business Day = 1/5/2022
4th Business Day = 1/7/2022
Last Business Day = 1/31/2022
Please, try the next function. It firstly creates an array of date respecting the function parameters conditions (business days for parameters in discussion), then extract first Nth
days and the last one, in an array. The Nth
days are placed in their own array, and last one as Date
, in the returned array second element:
Function NthBusinessDay(Nth As Long, FcstCurrency As String, MonthNumber As Long, YearNumber As Long) As Variant
Dim sh As Worksheet, lastR As Long, arr, arrFin, i As Long, k As Long, lastD As Date
Set sh = ActiveSheet
lastR = sh.Range("A" & sh.Rows.count).End(xlUp).row
arr = sh.Range("A2:C" & lastR).Value
ReDim arrFin(1 To UBound(arr)): k = 1
'build an array of dates mathing the function requirements:
For i = 1 To UBound(arr)
'Debug.Print Month(arr(i, 1)), Year(arr(i, 1)): Stop
If arr(i, 2) = FcstCurrency And Month(arr(i, 1)) = MonthNumber And _
Year(arr(i, 1)) = YearNumber And arr(i, 3) = "Business Day" Then
arrFin(k) = arr(i, 1): k = k + 1
End If
Next i
ReDim Preserve arrFin(1 To k - 1)
'Prepare the data to be returned
Dim arrFrst: ReDim arrFrst(1 To Nth): k = 1
For i = 1 To UBound(arrFrst)
arrFrst(k) = arrFin(i): k = k + 1
Next
'return in an array:
NthBusinessDay = Array(arrFrst, arrFin(UBound(arrFin)))
End Function
The above function should be called in the next way:
Sub testNthbusinessDay()
Dim arrRet, i As Long, strBD As String
arrRet = NthBusinessDay(4, "PLN", 1, 2022)
For i = 1 To UBound(arrRet(0))
strBD = strBD & "Business Day " & i & " = " & arrRet(0)(i) & vbLf
Next i
strBD = strBD & "Last Business Day = " & arrRet(1)
MsgBox strBD
End Sub