VBA to Delete Entire Row if Year is Older than Specified

jski21

Board Regular
Joined
Jan 2, 2019
Messages
133
Office Version
  1. 2016
Platform
  1. Windows
Good day Mr. Excel Team,

Seeking some brief instruction as to how to to delete an entire row of data if the year in the cell of that row precedes the year entered into a message box. Sample data is:

PR07 - Voucher Drawdowns EN Only.xlsx
ABCDEFGHIJKLMNOPQ
1NumberLine ItemProject IDAct IDNumberDateStatusStatusDateSentDateCodePrjctYearTypeRecipient TINPayee TINProgramYearAmountQtr/Yr
21706591221/29/1998Completed01/29/199801/28/1998B97MC3900041997EN11CDBG1998(77,591)1Q98
31742091217942/13/1998Completed02/13/199802/14/1999B97MC3900041997EN22CDBG199836,3491Q98
41742092218502/13/1998Completed02/13/199802/14/2000B97MC3900041997EN33CDBG19983171Q98
51742093220082/13/1998Completed02/13/199802/14/2001B97MC3900041997EN44CDBG19986481Q98
617420941922002/13/1998Completed02/13/199802/14/2002B97MC3900041997EN55CDBG19989501Q98
717420951922022/13/1998Completed02/13/199802/14/2003B97MC3900041997EN66CDBG19981,2661Q98
817420961922012/13/1998Completed02/13/199802/14/2004B97MC3900041997EN77CDBG19985541Q98
91776091223/2/1998Completed03/02/199802/27/2005B97MC3900041997EN88CDBG1998(50)1Q98
101799161218373/11/1998Completed03/13/199803/14/2006B97MC3900041997EN99CDBG1998111,9201Q98
111799162422313/11/1998Completed03/13/199803/14/2007B97MC3900041997EN1010CDBG1998185,6201Q98
121799163222103/11/1998Completed03/13/199803/14/2008B97MC3900041997EN1111CDBG1998572,7501Q98
13179916412822343/11/1998Completed03/13/199803/14/2009B97MC3900041997EN1212CDBG1998425,9041Q98
14179916512922363/11/1998Completed03/13/199803/14/2010B97MC3900041997EN1313CDBG1998455,4961Q98
1517992312922133/11/1998Completed03/13/199803/14/2011B97MC3900041997EN1414CDBG19982,1401Q98
1617992322922123/11/1998Completed03/13/199803/14/2012B97MC3900041997EN1515CDBG19989601Q98
1717992332922113/11/1998Completed03/13/199803/14/2013B97MC3900041997EN1616CDBG1998721Q98
1817992342922193/11/1998Completed03/13/199803/14/2014B97MC3900041997EN1717CDBG19986861Q98
1917992352922203/11/1998Completed03/13/199803/14/2015B97MC3900041997EN1818CDBG19982,5281Q98
2017992362922213/11/1998Completed03/13/199803/14/2016B97MC3900041997EN1919CDBG1998721Q98
2117992372922223/11/1998Completed03/13/199803/14/2017B97MC3900041997EN2020CDBG19985,5611Q98
2217992382922093/11/1998Completed03/13/199803/14/2018B97MC3900041997EN2121CDBG19987501Q98
2317992392922233/11/1998Completed03/13/199803/14/2019B97MC3900041997EN2222CDBG19985,0121Q98
24179923102922253/11/1998Completed03/13/199803/14/2020B97MC3900041997EN2323CDBG1998361Q98
25179923112922083/11/1998Completed03/13/199803/14/2021B97MC3900041997EN2424CDBG19982,5831Q98
26179923122922243/11/1998Completed3/13/199803/14/2022B97MC3900041997EN2525CDBG19983,1011Q98
PR07 - Voucher Drawdowns EN Onl



The date field used would be Column H. Example: If one enters "2022" all the rows with years from 2021 and prior would be deleted.

Thanks in advance for your review, consideration, and assistance.


jski
 

Excel Facts

Can you AutoAverage in Excel?
There is a drop-down next to the AutoSum symbol. Open the drop-down to choose AVERAGE, COUNT, MAX, or MIN
Seeking some brief instruction .....
One option:

- Filter the data for year <=2021 in column H
- Delete the unwanted rows (.SpecialCells(xlVisible).EntireRow.Delete, allowing for the possibility that there are no rows to be deleted)
- Unfilter.

The macro recorder will help you with the syntax.

Another option, if you can count on the dates in col H being in ascending order, would be to do a MATCH() using 31 Dec 2021, to find the last 2021 (or previous year) row number = N, say, and then delete rows 2 to N.

Please post back if you need help with the code.
 
Upvote 0
Thanks Stephen for the guidance. I noodled on this a bit and thought it easier to dissect the data using column O. Came up with some initial code:

'Declared Variables
Dim StartYear As String

'Open Input Box and Ask User for a StartYear. Filter Column O on <StartYear
Columns("O:O").Select
StartYear = Application.InputBox("Please provide a start year", "StartYear", Type:=1)

'Filter Column O based on input Box criteria
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15, Criteria1 _
:="<StartYear", Operator:=xlAnd
Rows("2:2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.ClearContents
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15
Range("A2").Select

Having some trouble moving the StartYear that was entered in the message box, into the actual AutoFilter criteria. This code unselects ALL the years for some reason. I believe I'm not correctly referencing the StartYear in the AutoFilter. Thoughts?
 
Upvote 0
Amazing what a short walk with some fresh air will do...

I believe this solves this issue, albeit a bit clunky maybe:

'Declared Variables
Dim StartYear As String


'Open Input Box and Ask User for a Start Year. Filter data on < StartYear,
Columns("O:O").Select
StartYear = Application.InputBox("Please provide a start year", "StartYear", Type:=1)


'Filter Column O based on Input Box criteria
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15, Criteria1 _
:="<" & StartYear, Operator:=xlAnd
Rows("2:2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.SpecialCells(xlVisible).EntireRow.Delete
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15
Range("A2").Select


'Delete blank table rows
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15, Criteria1 _
:="", Operator:=xlAnd
Rows("2:2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.SpecialCells(xlVisible).EntireRow.Delete
ActiveSheet.ListObjects("PR07Table").Range.AutoFilter Field:=15
Range("A2").Select
 
Upvote 0
Well done!

The macro recorder helps with the syntax, but generates flabby and clunky code. A cleaner version:

VBA Code:
Sub Test()

    Dim StartYear As String
    
    StartYear = Application.InputBox("Please provide a start year", "StartYear", Type:=1)
    
    Application.ScreenUpdating = False
    
    With Worksheets("Sheet1").ListObjects("PR07Table").DataBodyRange
        .AutoFilter Field:=15, Criteria1:="<" & StartYear
        On Error Resume Next
        Application.DisplayAlerts = False
        .SpecialCells(xlCellTypeVisible).Delete
        Application.DisplayAlerts = True
        On Error GoTo 0
        .AutoFilter
    End With

    Application.ScreenUpdating = True

End Sub
 
Upvote 0
Solution
Thanks Stephen. Your prompting in your initial response was integral in directing me down the right path to self-discover the answer. A good learning exercise for me. I' going to attempt the MATCH() option as I think it would be good to have both of these in my "hip pocket", so to speak. I'll report back.

Thanks again for the nudge!

jski
 
Upvote 0
Hi Stephen and other members,

Discovered another way via looping to get this done. Not useful for large datasets (mine took 75 mins. to run) but thought I would post it here to support other inquirers who may have a use for it with smaller datasets:
-------------------------------------------------------------------------------------------------------------------------------------
'Open Input Box and Ask User for a Start Year. (LOOP THROUGH ROWS AND DELETE BASED ON < StartYear)
' Columns("O:O").Select

'Turn Off Screen Updating
Application.ScreenUpdating = False

'StartYear = Application.InputBox("Please provide a start year:", "StartYear", Type:=1)
'
' LastRow = Cells(Rows.Count, 15).End(xlUp).Row
' For i = LastRow To 2 Step -1
' If Cells(i, 15).Value < StartYear Then Rows(i).EntireRow.Delete
' Next i

'Turn Off Screen Updating
Application.ScreenUpdating = False
-------------------------------------------------------------------------------------------------------------------------------------

I am having a challenge with the MATCH() method. You would have to use Column O for the MATCH rather than Column H as there might not be a true year end date (12/31/XX) in that column, and yes, Column H is sorted in ascending order. With that, I thought perhaps an alternative might be to seek to find the first instance in Column O of whatever year is input in the message box, define that row number, offset it by -1 (this would essentially select the row with the LAST day of the year preceding the one you selected), expand that row range to Row 2, and then delete all the rows. Here's what I have so far:


'Open Input Box and Ask User for a Start Year. (LOCATE FIRST INSTANCE OF StartYear AND DELTE ALL OLDER ROWS)
Columns("O:O").Select


'Turn Off Screen Updating
Application.ScreenUpdating = False

StartYear = Application.InputBox("Please provide a start year:", "StartYear", Type:=1)

StartRow = Columns("O:O").Find(What:=StartYear, After:=[O1], LookIn:=xlValues, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row
Set StartRow = n
Range("StartRow").Offset(-1, 0).Select

'Turn Off Screen Updating
Application.ScreenUpdating = False


This bombs off at Set StartRow = n as I'm missing an object and I'm not to certain how to proceed to finish at this point. Thanks all.
 
Upvote 0
It is very confusing what you are trying to do here:
VBA Code:
StartRow = Columns("O:O").Find(What:=StartYear, After:=[O1], LookIn:=xlValues, SearchOrder:=xlByRows, _
    SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row
Set StartRow = n
You seem to initially set StartRow equal to a row number (which would make it a number).
Then, on the next line, you seem to be trying to set StartRow to "n", which isn't designed anywhere.
So I have no idea what you are trying to do on that line.

Also, you only use the "Set" command when setting objects, like Ranges, Worksheets, Workbooks, etc.
You NEVER use "Set" when setting numeric or text variables (like a row number).

If n was a number that was calculated or set earlier, and you wanted to set "StartRow" equal to that number, you would just use:
VBA Code:
StartRow = n
 
Upvote 0
Thanks Joe4. Which is why I'm a bit lost. Tried to proceed in uncharted VBA territory for me. After setting StartRow to a row number by:

StartRow = Columns("O:O").Find(What:=StartYear, After:=[O1], LookIn:=xlValues, SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Row

How would I then take that row number, movie it up one row, expand that range to row 2 and delete all the rows?
 
Upvote 0
How would I then take that row number, movie it up one row, expand that range to row 2 and delete all the rows?
Do you mean something like this:
VBA Code:
If StartRow > 2 Then Rows("2:" & StartRow -1).Delete
 
Upvote 0

Forum statistics

Threads
1,214,585
Messages
6,120,388
Members
448,957
Latest member
Hat4Life

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top