Bernie Deitrick said:
You could use a UDF - see the code below. Use it like ...
. . . note that this will not find dates like "March 11, 2003" ...
'Date Version
Function GetDate(strInput As String) As Variant
Dim myVals As Variant
Dim i As Integer
Dim myDate As Date
myVals = Split(strInput, " ")
Which means any date immediately followed by punctuation, e.g.,
On 7/25/2007, Bernie Dietrick posted a suboptimal udf.
will include the punctuation mark in the entry in myVals.
Unnecessary, and On Error Resume Next would have made more sense.
For i = LBound(myVals) To UBound(myVals)
myDate = DateValue(myVals(i))
This throws an error if the string isn't a date. BUT, if it IS a date,
then myDate contains that date . . .
GetDate = DateValue(myVals(i))
. . . which means this second DateValue call is pointless. Eliminate
myDate and the first of these assignment statements
Exit Function
TryDate:
Next i
GetDate = "-NULL-"
Questionable return value. You could have returned an error value, or
"" or a negative number of large absolute value (so it wouldn't be
confused with a date in 1904 date system).
Exit Function
ErrHandler:
Resume TryDate
End Function
...
Spaghetti code at its, er, finest!
If this approach made sense (it doesn't), then at least use sensible
control flow.
Function foo(s As String) As Variant
Dim t As Variant
foo = "" 'return value for no date found
On Error Resume Next
For Each t In Split(s, " ")
foo = DateValue(t)
If Err.Number <> 0 Then Err.Clear Else Exit For
Next t
End Function
But even better would be using a more intelligent approach.
Function foo2(s As String) As Variant
'requires a VBA reference to
'Microsoft VBScript Regular Expressions 5.5
Const MONM As String = _
"Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|" & _
"January|February|March|April|May|June|" & _
"July|August|September|October|November|December"
Dim re As New RegExp, mc As MatchCollection
With re
.Global = True
.IgnoreCase = True
.Pattern = "\b(\d{1,2}[-/]\d{1,2}[-/](\d{2}){1,2})|" & _
"(\d{4}-\d{2}-\d{2})|((" & MONM & ")\d{1,2}(,?\s*\d{4})?)|" & _
"(\d{1,2}[- ]*(" & MONM & ")([- ]*\d{2,4})?)\b"
Set mc = .Execute(s)
End With
foo2 = IIf(mc.Count > 0, CDate(mc.Item(0).Value), "")
End Function
This should find any substring Excel itself would consider a date.