I'd like to determine if the dates in Column B fall between two dates (the first day of month m year n and the last day of month m-1 year n+1) in several periods. For example, does 9/20/2013, a cell value in column B, fall between:
7/1/2010 and 6/30/2011
7/1/2011 and 6/30/2012
7/1/2012 and 6/30/2013
7/1/2013 and 6/30/2014
7/1/2015 and 6/30/2016
If True then a cell value in the same row of column C will contain the year of the end period where the date falls (in this case 2014) and will return a blank cell if False. Below is the data set in column B that I need to examine:
9/11/2013
8/20/2015
8/22/2013
8/31/2001
(Blank cell)
8/31/2009
AAA
9/3/2013
(Blank cell)
9/25/2011
9/30/2013
10/10/2012
Anna
10/4/2015
First I examined with the following code:
Sub CheckMyYear1_Click()
Dim i As Long, j As Long, Last_Row As Long, Period As Long
T0 = Timer
Last_Row = Cells(Rows.Count, "B").End(xlUp).Row
Period = 5
For j = 2 To Last_Row
For i = 1 To Period
Begin_Period = DateSerial(Year(Date) - i, Month(Date), 1)
End_Period = DateSerial(Year(Date) - i + 1, Month(Date), 0)
If Cells(j, "B") >= Begin_Period And Cells(j, "B") <= End_Period Then
Cells(j, "C") = Year(End_Period)
Exit For
End If
Next i
If Cells(j, "C") = "" Then
Cells(j, "C") = "Out of Period"
Cells(j, "C").Font.Color = RGB(226, 107, 10)
End If
If Cells(j, "B") = "" Then
Cells(j, "C") = "No Data"
Cells(j, "C").Font.Color = vbRed
ElseIf IsDate(Cells(j, "B").Value) = False Then
Cells(j, "C") = "Not Date"
Cells(j, "C").Font.Color = vbRed
End If
Next j
Range("C2:C" & Last_Row).Copy
InputBox "The runtime of this program is ", "Runtime", Timer - T0
End Sub
It worked fine and returned the correct outputs. To improve the performance since the size of data set could be large, I stored the data set in an array and looped through the array to examine each of its elements. Here is the code I used:
Sub CheckMyYear2_Click()
Dim i As Long, j As Long, Last_Row As Long, Period As Long
T0 = Timer
Last_Row = Cells(Rows.Count, "B").End(xlUp).Row
Period = 5
ReDim MyDate(2 To Last_Row, 1 To 1)
ReDim MyYear(2 To Last_Row, 1 To 1)
MyDate = Range("B2:B" & Last_Row).Value
For j = 2 To Last_Row
For i = 1 To Period
Begin_Period = DateSerial(Year(Date) - i, Month(Date), 1)
End_Period = DateSerial(Year(Date) - i + 1, Month(Date), 0)
If MyDate(j, 1) >= Begin_Period And MyDate(j, 1) <= End_Period Then
MyYear(j, 1) = Year(End_Period)
Exit For
End If
Next i
If MyYear(j, 1) = "" Then
MyYear(j, 1) = "Out of Period"
Cells(j, "C").Font.Color = RGB(226, 107, 10)
End If
If MyDate(j, 1) = "" Then
MyYear(j, 1) = "No Data"
Cells(j, "C").Font.Color = vbRed
ElseIf IsDate(MyDate(j, 1).Value) = False Then
MyYear(j, 1) = "Not Date"
Cells(j, "C").Font.Color = vbRed
End If
Next j
Range("C2:C" & Last_Row).Value = MyYear
Range("C2:C" & Last_Row).Copy
InputBox "The runtime of this program is ", "Runtime", Timer - T0
End Sub
The run-time error '9' occurred using the above code. I then hit F8 to know where did the arrow point at, but the arrow didn't point at any lines.
Does anyone here know how to fix the error? I'm also interested in knowing the better way to do the task above.
On Error GoTo ErrHandlerat the top, and anErrHandler:label at the bottom, preceded byExit Suband followed byStopand thenResume. When the error occurs, the cursor should be on theStopkeyword; F8 to theResumekeyword, and another F8 to jump to the exact statement that blew up.ErrHandler:ElseIf IsDate(MyDate(j, 1).Value) = False Then.MyDate(j, 1)is no more a range object. So it has not a value property. Should beElseIf IsDate(MyDate(j, 1)) = False Then