2

I was writing a code that automatically checks if a cell (in column K) contains a date. It only should give an error if column K doesn't contain a date AND the date in column L is more than 30 days ago.

I've found out that my code works, but not for all dates. So I Debug.print and saw that he just ignores the fact that the if requirement isn't met. I've never experienced this.

This is the code (under it you'll find the debug)

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

I've found that cell 22217 contains a case where he should give an error. But he doesn't, the whole document contains more than 29000 rows. It gives me 58 errors but in reality there're way more.

This is the debug info I got (Check if date is empty (Column L) / Column K + 30 days / today)

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

As you can see it recognises that row 22217 is empty and the date is longer than 30 days. So it should be triggered. I found out that it is this line that doesn't work properly: ActiveWorkbook.Sheets("Acknowledgements follow up").Range("K" & i) + 30 > Date

Any ideas? Thanks! KawaRu

Community
  • 1
  • 1
KawaRu
  • 64
  • 1
  • 9
  • All this code does is just check if there's a date in a cell??? – dwirony Nov 06 '17 at 16:00
  • Something went wrong with the paste :) I fixed it – KawaRu Nov 06 '17 at 16:01
  • @cxw It checks if column L is empty and if Column K is older than 30 days. If these two requirements are met it should give a pop up. Which it doesn't for some reason. I have fixed it in my description. Thanks for pointing out! – KawaRu Nov 06 '17 at 16:11
  • because you don't have MsgBox MsgString – QHarr Nov 06 '17 at 16:14
  • I do further in code. It gives me 58 lines where there is an error. But in reality there should be more than 100. So I don't get why it works for those 58 but not for the others. I have added the rest of my code – KawaRu Nov 06 '17 at 16:16
  • Please edit it back in if you are stating that no message is appearing. And who ever downvoted me for responding by saying add msgbox, when it was clearly missing, shame on you. – QHarr Nov 06 '17 at 16:19
  • 1
    KawaRu: the test `Kx + 30 > Date` is testing whether the value in column K is *within* the last 30 days, not *older* than 30 days. `Kx < (Date-30)` would test for older than 30 days. Which do you want? – cxw Nov 06 '17 at 16:21
  • I tried it seperated for the code. The cell is a date but still it doesn't want to recognize that a date from 2013 is older than today - 30 days. – KawaRu Nov 06 '17 at 16:24

1 Answers1

4

This works on my system for testing dates older than 30 days:

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

My test data was:

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

The result I get is:

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

Edit

The algorithmic problem was the date test. Kx + 30 > Date tests whether the value in column K is within the last 30 days, not older than 30 days. In the code above, Kx < (Date - 30) tests for older than 30 days. (Kx + 30) < Date (less than) would do the same.

An improvement on the code above would be to rename CK and CL. Instead of naming them after their locations, name them after their meanings. E.g., COL_ACK_RECEIVED or something. That will make it easier to understand your code when you come back to it later.

Edit 2

  • As @HarassedDad noted in a comment, be careful of d/m/y vs. m/d/y and other date-format issues.
  • "Older than 30 days" might mean < Date - 30 or <= Date - 30, depending on your requirements.
  • For future readers who may be looking at adapting this, remember that "30 days ago" and "last month" are very different!
  • This answer regarding Range.Value is a good one. I will add that using CStr() or other converter functions is a good practice, since Range.Value returns a Variant.
  • This question and this question, and their answers, are good reading re. why = "" might not always match a cell that appears to be empty.
cxw
  • 16,685
  • 2
  • 45
  • 81
  • This indeed works! Thank you, still don't know for sure what went wrong with my code as it works for some rows. Thank you for your hints I'll keep them in mind :) Have a nice day! – KawaRu Nov 06 '17 at 16:32
  • Just remember that 01-09-13 is either 1st September 2013 or 9th January 2013. And that Excel will not consistently interpret dates the same way. (Actually depending on your local settings it could interpret it as 13th September 2001 in some circumstances) – Harassed Dad Nov 06 '17 at 16:37
  • I wish I could upvote this answer twice. Actually, I wish all SO answerers put as much effort in their posts! Keep 'em coming! – Mathieu Guindon Nov 06 '17 at 16:41
  • @Mat'sMug Thanks for the kind words and the encouragement! I greatly appreciate it. – cxw Nov 06 '17 at 16:47