Below is a VBA solution that should work and be relatively fast.
I'm adding all items in the range that match the year and month to an ArrayList
. Then, I'm sorting that list in ascending order and picking the last item in the list (this item should possess the largest value in the set).
This is running in less than a second going through a list of about 800 items.
Function:
Option Explicit
Public Function MaxDateInRange(SearchRange As Range, _
YearNumber As Long, _
MonthNumber As Long) As String
Dim cell As Range
Dim ListIndex As Long
Dim List As Object: Set List = CreateObject("System.Collections.ArrayList")
'Go through all cells, and all items that match the month and year to a list
For Each cell In SearchRange
If IsDate(cell) Then
If Month(cell) = MonthNumber And Year(cell) = YearNumber Then List.Add (cell)
End If
Next
'Sort the list ascending, then select the last item in that list
List.Sort
ListIndex = List.Count - 1
'Bounds check, to see if anything was found, otherwise return ""
If ListIndex >= 0 Then
MaxDateInRange = List(ListIndex)
Else
MaxDateInRange = vbNullString
End If
End Function
Usage:
Public Sub Example()
Dim rng As Range: Set rng = Sheets(2).Range("D1:D795")
Dim t As Double
t = Timer
Debug.Print MaxDateInRange(rng, 2019, 3)
Debug.Print MaxDateInRange(rng, 2019, 4)
Debug.Print "Process took " & Timer - t
End Sub
Debug Output based on sample data:
2019-03-28
2019-04-25
Process took 0.04296875
VBA
but this is easily done through functions too If you want – JvdV=MAX((MONTH($A$1:$A$18)=4)*(A1:A18))
where I have various dates in a1:a18 – Nathan_Sav=INDEX($A:$A,MATCH(EOMONTH(DATE(1995,4,1),0),$A:$A,1))
. This figures out the actual last day of the month and then finds the largest number that is less than or equal to that. – Darren Bartrup-Cook