如何检查单元格中的日期是实际日期还是字符串日期?

How to check if the date in a cell is an actual date or a string date?

在工作中,我们使用 Office 365 Excel 的文件作为预订系统。每个站点都有多个选项卡,每个记录都有一个预订日期。存在日期格式问题 - 基本上默认区域设置为 "mm/dd/yyyy",但日期显示为 "dd/mm/yyyy"。当人们手动添加行(通常每天自动生成预订时段)并且只是以错误的格式输入日期而不是从它显示正确的相邻单元格复制日期值时,但顶部栏中的单元格值不同,但是在 Desktop App 中打开此文件时,它根本不会将其视为不同的值。只有在应用过滤器时,才有日期和字符串日期值可以作为过滤依据。这会导致某些日期在创建报告或基于日期导入数据时未被宏选取。

我一直在考虑编写一个实用程序宏,根据当前日期前后的日期清理所有日期,但是我不确定这是否是最好的方法。我不认为我可以只更改所有用户的语言环境设置,就像我在文档中阅读的那样,这只会对单个用户设置进行更改,我不确定这将如何影响整个系统的整体功能。有什么方法可以比解析这个庞大的文件或手动查找这个日期更容易完成吗?

这真的很痛苦,因为这个文件是在我加入团队之前很久就设计的,现在我正努力让它更不容易出错。

提前感谢您提供任何线索!

实际日期是数字。所以你可以检查 IsNumeric

If IsNumeric(Range("A1").Value2) Then
    Debug.Print "date"
Else
    Debug.Print "string"
End If

请注意,您需要检查 .Value2 而不是 .Value

看来您的问题源于人们输入的日期无效。 您可以尝试对单元格应用数据验证以在数据输入期间进行清理。 数据验证允许将单元格设置为日期,然后您可以指定日期范围。因此只允许该范围内的有效日期。

Peh 的回答引导我找到了正确的解决方案。如果有人遇到类似问题,这里是完整的代码:

Sub SanitizeDates()
    ' ---
    ' Utility macro that goes over all live sheets and checks all rows
    ' for the string dates that have been input manually
    ' and converts it to an actual Date values.
    ' ---

    Debug.Print "--- Log Start"
    
    Dim Prompt As String
    Dim Errors As Integer
    Dim TotalErrors As Integer
    TotalErrors = 0
    Errors = 0

    Dim Tracker As Workbook
    Dim WS As Worksheet
    
    Dim CurrentDateValue As Variant
    Dim NewDate As Date
    Dim RowCount As Long
    Dim nRow As Long
    
    Set Tracker = ThisWorkbook
    
    Application.ScreenUpdating = False
    
    For Each WS In Tracker.Worksheets
        If WS.Visible And Not WS.Name = "Matrix" Then ' if worksheet is not visible and not a Matrix
            If InStr(1, WS.Name, "Template", vbTextCompare) = 0 Then ' if worksheet is not a template
            
                Errors = 0
                
                RowCount = WS.ListObjects(1).DataBodyRange.Rows.Count
                
                'loop over all rows in table
                For nRow = 1 To RowCount
                    With WS.ListObjects(1).DataBodyRange
                    
                        ' check if the cell is a black bar / divider
                        If Not .Cells(nRow, 3).Interior.Color = RGB(0, 0, 0) Then
                            If Not IsNumeric(.Cells(nRow, 3).Value2) Then
                                                                
                                On Error GoTo SkipInvalid
                                NewDate = DateValue(.Cells(nRow, 3).Value2)
                                .Cells(nRow, 3).Value2 = NewDate
                                Errors = Errors + 1
                                
                                'Error logging
                                'Call LogError(.Cells(nRow, 5), .Cells(nRow, 15), "Date Format - dev")
                            End If
                        End If
                    End With
SkipInvalid:
                Next nRow
                
                TotalErrors = TotalErrors + Errors
                
                If Errors Then
                    Prompt = Prompt & "Found " & Errors & " errors in " & WS.Name & vbCrLf
                    Debug.Print "Found " & Errors & " errors in " & WS.Name
                End If
                
            End If
        End If
    Next WS
    
    Application.ScreenUpdating = True
    
    Debug.Print "--- Log End"
    
    If TotalErrors Then
        MsgBox (Prompt & vbCrLf & vbCrLf & _
            "Total of " & TotalErrors & " errors found. All data sanitized successfully.")
    Else
        MsgBox ("No errors found")
    End If
End Sub