从此网站和其他网站上的先前问题中,我获得了一个可以解析并查找文本字符串或单元格中的日期的函数。以下是该函数:
Function GetDate(strInput As String) As Date
Dim DateFormat() As String
Dim intDateLength As Integer
Dim intMaxFormat As Integer
Dim intFrmtCtr As Integer
Dim intPosition As Integer
intMaxFormat = 6
ReDim DateFormat(1 To intMaxFormat)
DateFormat(1) = "*##[-/]##[/-]####*"
DateFormat(2) = "*#[-/]##[-/]####*"
DateFormat(3) = "*##[-/]#[-/]####*"
DateFormat(4) = "*##[-/]##[-/]##*"
DateFormat(5) = "*#[-/]##[-/]##*"
DateFormat(6) = "*#[-/]#[-/]##*"
GetDate = Now
For intFrmtCtr = 1 To intMaxFormat
If strInput Like DateFormat(intFrmtCtr) Then
intDateLength = Len(DateFormat(intFrmtCtr)) - 8
strInput = Replace(strInput, " ", "")
For intPosition = 1 To Len(strInput)
If Mid(strInput, intPosition, intDateLength) Like DateFormat(intFrmtCtr) Then
GetDate = DateValue(Mid(strInput, intPosition, intDateLength))
Exit Function
End If
Next intPosition
End If
Next intFrmtCtr
End Function
然后通过引用单元格地址来调用它:
'Gets date from cell A2
Range("A2").Select
dateWork = GetDate(Selection)
然后我可以使用或类似方法格式化输出Format(dateWork, "mmddyy")
。
在上面的例子中,给定一个单元格,返回8/31/2011
字符串的内容。08312011
但是,从单元格内容日期为一位数(即月初)开始,该函数开始返回年份的前两位数字,而不是后两位数字。突然间,日期开始看起来像是 2020 年的,而不是 2011 年的。
我已经能够使用其他方面相同的输入数据表对此进行测试,其中直到并包括的日期8/31/2011
都正确返回,9/1/2011
并且以“20”开头的日期都返回“20”作为年份。
这个功能是哪里出现故障了?
更新问题澄清:
我在多个宏中使用此功能,这些宏作用于从报告生成工具 (Business Objects) 导出的数据。可以手动编辑输入文件中的日期,但这违背了宏的目的,因此不应被视为一种选择。
可以调用 GetDate() 函数来查找任何字符串中的日期。字符串可以是各种格式的日期,也可以是文本和日期的组合,例如“截至 1977 年 9 月 13 日的总数”。
只要它保留上面列出的功能,我将非常感激您对该功能的简化或编辑。
答案1
您的Mid(strInput, intPosition, intDateLength)
不适合您。对于 2011 年 9 月 1 日,您匹配 DateFormat(6) = "*#[-/]#[-/]##*"
。因此Mid(strInput, intPosition, intDateLength) = Mid("9/1/2011", 1, 6)
和 返回“9/1/20”而不是“2011 年 9 月 1 日”。
根据上面的例子,我认为你需要添加 2 个模式,以便涵盖 1 和 2 位月份/日期以及 2 和 4 位年份的所有组合。顺序很重要,因为你想先匹配 4 位年份(请注意,你遇到问题的原因是#/#/##匹配 9/1/2011,而实际上您只希望它匹配 9/1/11。因此代码更改如下所示。我尚未对所有日期格式进行详尽测试,但似乎没问题。
intMaxFormat = 8
ReDim DateFormat(1 To intMaxFormat)
DateFormat(1) = "*##[-/]##[/-]####*"
DateFormat(2) = "*#[-/]##[-/]####*"
DateFormat(3) = "*##[-/]#[-/]####*"
DateFormat(4) = "*#[-/]#[-/]####*"
DateFormat(5) = "*##[-/]##[-/]##*"
DateFormat(6) = "*##[-/]#[-/]##*"
DateFormat(7) = "*#[-/]##[-/]##*"
DateFormat(8) = "*#[-/]#[-/]##*"
答案2
为了接受 2 位和 4 位数字的年份(其中 2 位数字小于 1000),我使用了一行来检查所有有关日期的信息,即:
If IsDate(date) And Len(Trim(Year(date))) = 2 Or Len(Trim(Year(date))) = 4 Then
GoTo Action 'Continue with the macro
Else: "Your Message"
End If
答案3
我写了一个更短的宏,应该可以满足您的要求。它通过空格字符将字符串拆分为一个数组。然后,宏会遍历数组以查找日期。如果日期附加了多余的字符,则它会失败。但是,如果日期是其“自己的单词”,两端用空格隔开,则它会完美运行。根据您的需要,可能需要对其进行一些修改。
Function GetDate(strInput As String) As Date
Dim strDate() As String, i As Long
strDate = Split(strInput, " ")
For i = 0 To UBound(strDate) - 1
If Right(strDate(i), 1) = "." Then strDate(i) = Left(strDate(i), Len(strDate(i)) - 1)
If IsDate(strDate(i)) Then
GetDate = strDate(i)
Exit For
End If
Next i
End Function