Just for a twist, I'd prefer to use this regex:
((0[1-9]|1[0-9]|2[0-9]|3[0-1])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)([0-9][0-9][0-9][1-9]))
Which will filter out strings like 00FOO
or 99DEX
and that sort of thing for the day and month. Also will reject if the year is 0000
.
There are 3 capturing groups so the day, month and year can be pulled out with SubMatches(i)
.
The max date is found by using the WorksheetFunction.Max
function on an array populated with the matches themselves - so no manipulation of worksheet data is done to get the answer:
Option Explicit
Sub Test()
MsgBox ExtractMaxDate(Sheet1.Range("A1"))
End Sub
Function ExtractMaxDate(str As String) As Date
Dim objRegex As Object 'RegExp
Dim objMatches As Object 'MatchCollection
Dim varDates() As Long
Dim i As Long
Dim strMaxDate As String
Set objRegex = CreateObject("VBScript.RegExp")
With objRegex
.Global = True
.IgnoreCase = True
' will not match days > 31 or strings that are not months or year 0000
.Pattern = "((0[1-9]|1[0-9]|2[0-9]|3[0-1])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)([0-9][0-9][0-9][1-9]))"
End With
' run regex
Set objMatches = objRegex.Execute(str)
' any matches ?
If objMatches.Count > 0 Then
' re-dim the array to number of matches
ReDim varDates(0 To objMatches.Count - 1)
For i = 0 To objMatches.Count - 1
' get date as yyyy-mm-dd and use CDate and store in array of Long
varDates(i) = CDate(objMatches(i).SubMatches(3) & _
"-" & objMatches(i).SubMatches(2) & _
"-" & objMatches(i).SubMatches(1))
Next i
' get the max date out of the matches
strMaxDate = CDate(WorksheetFunction.Max(varDates))
Else
' no matches
strMaxDate = 0
End If
ExtractMaxDate = strMaxDate
End Function