我需要将电子表格列中的内容从文本转换为日期。
单元格格式为文本,并要求输入者输入日期“ ddmmyyyy”。
发生了事故,我发现了一些无法解析为日期的内容,包括诸如“未知”之类的条目。
因此,我使用了一个声明为日期的变量,并编写了一个错误处理程序来处理无法解析的内容。
现在我无法锻炼了。
如果日期是2000年3月3日,并且有人将其输入为“ 03332000”,则由于“ 33”不能是一个月或一天而无法解析;它被我想要的错误处理程序捕获。
但是,如果输入的是“ 03132000”,我想不出一种方法来防止VBA将其转换为“ 13/03/2000”作为有效日期。
声明日期变量的格式不会阻止VBA解析日期。
我可以编写一些东西来测试字符串中日期和月份部分的数字范围,但这是多余的代码行,我希望只是通过错误处理程序来做到这一点。
答案 0 :(得分:1)
我会稍有不同,让Excel来完成工作。
Public Function ValidateDate(ByVal strDate As String) As Boolean
Dim intDay As Integer, intMonth As Integer, intYear As Integer, dtDate As Date
ValidateDate = True
On Error GoTo IsInValid
If Len(strDate) <> 8 Then GoTo IsInValid
If Not IsNumeric(strDate) Then GoTo IsInValid
intDay = Left(strDate, 2)
intMonth = Mid(strDate, 3, 2)
intYear = Right(strDate, 4)
dtDate = DateSerial(intYear, intMonth, intDay)
If DatePart("d", dtDate) <> intDay Then GoTo IsInValid
If DatePart("m", dtDate) <> intMonth Then GoTo IsInValid
If DatePart("yyyy", dtDate) <> intYear Then GoTo IsInValid
Exit Function
IsInValid:
ValidateDate = False
End Function
...这将确保与leap年等相关的所有内容仍能正常工作,并确保所有条目均得到正确验证。
答案 1 :(得分:0)
如果您放置:
03332000
在单元格 A1 中运行:
Sub CheckDate()
Dim s As String, d As Date
s = Range("A1").Text
d = DateSerial(CInt(Right(s, 4)), CInt(Mid(s, 3, 2)), CInt(Left(s, 2)))
MsgBox s & vbCrLf & d
End Sub
您将获得:
因此,即使有效月份只能在[1-12]范围内,Excel也会通过将33解释为对未来日期的预测来尝试“帮助”您。例如,如果输入的月份为13,Excel会将其视为下一年的 12月!
您不能依赖于错误处理。您需要像这样的检查:
Sub CheckDate2()
Dim s As String, d As Date
Dim dd As Integer, mm As Integer, yr As Integer
s = Range("A1").Text
yr = CInt(Right(s, 4))
mm = CInt(Mid(s, 3, 2))
dd = CInt(Left(s, 2))
If yr = 0 Or yr < 1900 Then
MsgBox "year is bad"
Exit Sub
End If
If dd = o Or dd > 31 Then
MsgBox "day is bad"
Exit Sub
End If
If mm = 0 Or mm > 12 Then
MsgBox "month is bad"
Exit Sub
End If
d = DateSerial(yr, mm, dd)
MsgBox s & vbCrLf & d
End Sub
您还可以进行其他检查,例如查看字段的长度等。