并非所有日期都被VBA识别

时间:2017-11-06 15:58:08

标签: vba excel-vba date if-statement excel

我正在编写一个代码,用于自动检查单元格(在K列中)是否包含日期。如果列K不包含日期且列L中的日期超过30天,则只会出错。

我发现我的代码有效,但并非适用于所有日期。所以我Debug.print看到他忽略了if要求未得到满足的事实。我从来没有经历过这个。

这是代码(在它下面你会发现调试)

Aantal = 0
i = 0
LastRow = 0
k = 0
LastRow = ThisWorkbook.Sheets("Acknowledgements follow up").Range("A1").End(xlDown).Row
'For i = 2 To LastRow
For i = 22214 To 22222
Debug.Print ActiveWorkbook.Sheets("Acknowledgements follow up").Range("L" & i).Value & "      " & ActiveWorkbook.Sheets("Acknowledgements follow up").Range("K" & i) + 30 & "      "; Date & vbCrLf
    If ActiveWorkbook.Sheets("Acknowledgements follow up").Range("L" & i).Value = "" And ActiveWorkbook.Sheets("Acknowledgements follow up").Range("K" & i) + 30 > Date Then
    Aantal = Aantal + 1
    MsgString = MsgString & i & " / "
    End If
Next i
If MsgString <> "" Then MsgString = Left(MsgString, Len(MsgString) - 3)

If Aantal > 1 Then
MsgBoxAnswer = MsgBox("There are " & Aantal & " dates missing in the acknowlegement sheet" & vbCrLf _
& "The missing dates are on rows " & MsgString, vbOKOnly + vbExclamation, "Missing dates")
End If

If Aantal = 1 Then
MsgBoxAnswer = MsgBox("There is " & Aantal & " date missing in the acknowlegement sheet" & vbCrLf _
& "The missing date is on row " & MsgString, vbOKOnly + vbExclamation, "Missing dates")
End If

我发现单元格22217包含他应该给出错误的情况。但他并不是,整个文档包含超过29000行。它给了我58个错误,但实际上还有更多。

这是我收到的调试信息(检查日期是否为空(列L)/列K + 30天/今天)

  

05-08-13 01-09-13 06-11-17

     

05-08-13 01-09-13 06-11-17

     

05-08-13 01-09-13 06-11-17

 01-09-13      06-11-17
     

05-08-13 04-09-13 06-11-17

     

06-08-13 04-09-13 06-11-17

     

05-08-13 04-09-13 06-11-17

     

05-08-13 04-09-13 06-11-17

     

30-12-13 04-09-13 06-11-17

如您所见,它识别出行22217为空且日期超过30天。所以它应该被触发。我发现这条线不能正常工作:ActiveWorkbook.Sheets("Acknowledgements follow up").Range("K" & i) + 30 > Date

有什么想法吗? 谢谢! KawaRu

1 个答案:

答案 0 :(得分:4)

这适用于我的系统,用于测试超过30天的日期

Option Explicit ' Always start every VBA file with this
Option Base 0   ' Not as important, but I use it as a reminder to myself

Public Sub KawaRu()
    Dim CL As Long, CK As Long  ' Column numbers for L, K
    CL = AscW("L") - AscW("A") + 1
    CK = AscW("K") - AscW("A") + 1

    ' Always Dim your variables, and use Option Explicit
    Dim aantal As Long, i As Long, LastRow As Long, k As Long
    Dim MsgString As String
    aantal = 0
    i = 0
    k = 0

    ' Avoid repeating references to objects.  Instead, save them in a variable.
    Dim sh As Worksheet
    Set sh = ActiveWorkbook.Sheets("Acknowledgements follow up")

    LastRow = sh.Range("A1").End(xlDown).Row

    For i = 1 To LastRow
        Debug.Print sh.Range("L" & i).Value, sh.Range("K" & i) + 30, Date
        ' Use Cells() for speed when you're in a loop.
        If sh.Cells(i, CL).Value = "" And _
                sh.Cells(i, CK) < (Date - 30) Then
              ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ older than 30 days
            aantal = aantal + 1
            MsgString = MsgString & i & " / "
        End If
    Next i

    Debug.Print aantal
    If MsgString <> "" Then MsgString = Left(MsgString, Len(MsgString) - 3)

    Dim MsgBoxAnswer As VbMsgBoxResult

    If aantal > 1 Then
        MsgBoxAnswer = MsgBox("There are " & aantal & " dates missing in the acknowlegement sheet" & vbCrLf _
            & "The missing dates are on rows " & MsgString, vbOKOnly + vbExclamation, "Missing dates")
    End If

    If aantal = 1 Then
        MsgBoxAnswer = MsgBox("There is " & aantal & " date missing in the acknowlegement sheet" & vbCrLf _
        & "The missing date is on row " & MsgString, vbOKOnly + vbExclamation, "Missing dates")
    End If

End Sub

我的测试数据是:

col. A       K              L             M
x            5/8/2013       1/9/2013      6/11/2017
x            1/9/2013                     6/11/2017
x            1/9/2013                     6/11/2017
x            11/1/2017                    6/11/2017

我得到的结果是:

There are 2 dates missing in the acknowledgement sheet
The missing dates are on rows 2/ 3

修改

算法问题是日期测试。 Kx + 30 > Date测试K列中的值是否在过去30天内,而不是超过30天。在上面的代码中,Kx < (Date - 30)测试超过30天。 (Kx + 30) < Date(小于)会做同样的事情。

上述代码的改进是重命名CKCL。不是在位置之后命名它们,而是在它们的含义之后命名它们。例如,COL_ACK_RECEIVED或其他东西。这将使您在以后再回到它时更容易理解您的代码。

修改2

  • 正如@HarassedDad在评论中指出的那样,要小心d / m / y与m / d / y和其他日期格式问题。
  • &#34;超过30天&#34;可能意味着< Date - 30<= Date - 30,具体取决于您的要求。
  • 对于未来可能正在考虑适应这种情况的读者,请记住&#34; 30天前&#34;和#34;上个月&#34;非常不同!
  • This answer关于Range.Value是一个很好的问题。我将补充一点,使用CStr()或其他转换器函数是一种很好的做法,因为Range.Value会返回一个Variant。
  • This questionthis question以及他们的答案都是很好的阅读。为什么= ""可能并不总是与看似空的单元格匹配。