Home » excel » VBA Excel – Is there a way to delete rows based on criteria in two columns?

VBA Excel – Is there a way to delete rows based on criteria in two columns?

Posted by: admin May 14, 2020 Leave a comment


I’ve been working on a macro to clean up a form generated and copied into Excel. I have everything figure out up until the last stage where I need to delete the rows that contain extranious formulas.

400000  |  Smith, John| 2.4   | 5.66|   =C1+D1
400001  |  Q, Suzy    | 4.6   | 5.47|   =C2+D2
400002  |  Schmoe, Joe| 3.8   | 0.14|   =C3+D3
Blank   |             |       |     |   #VALUE
Blank   |             |       |     |   #VALUE

Is there a formula to compare column ‘A’ to column ‘E’ and have it delete all rows with no value in ‘A’, but a value in ‘E’?

I’ve tried a basic loop formula going solely by the empty ‘A’ column which worked to the point of forever deleting rows below the information I want to keep, and I found a formula dealing with filters on this website (from brettdj) but I did not know how to edit it to properly capture what I needed.

This is what I have from brettdj:

Sub QuickKill()
Dim rng1 As Range, rng2 As Range, rng3 As Range
Set rng1 = Cells.Find("*", , xlValues, , xlByColumns, xlPrevious)
Set rng2 = Cells.Find("*", , xlValues, , xlByRows, xlPrevious)
Set rng3 = Range(Cells(rng2.Row, rng1.Column), Cells(1, rng1.Column))
Application.ScreenUpdating = False
With rng3.Offset(-1, 1).Resize(rng3.Rows.Count + 1, 1)
    .FormulaR1C1 = "=OR(RC1="",RC1<>"")"
    .AutoFilter Field:=2, Criteria1:="TRUE"
    On Error Resume Next
    'in case all rows have been deleted
    On Error GoTo 0
End With
Application.ScreenUpdating = True

Some other information:

The first 5 rows of the sheet I want to ignore, they hold column titles and the report name, etc.

The number of rows filled by 40


#’s changes, so I can’t simply have the macro delete row 4 to whatever.

I don’t have extensive knowledge of macro’s (obviously) so detailed explanations of how certain portions work would be appreciated.
Thanks in advance for any help.

How to&Answers:

yes there is a way that doesn’t need a loop

your formula (in Excel spreadsheet) would be something like this:


now, it is possible get that formula to put an error in the rows where I test returns True. The reason we would do this is a feature of Excel called SpecialCells.

In Excel select any empty cell, and in the formula bar type


Next, hit F5 or CTRL+G (Go to… on the Edit menu) then click the Special button to show the SpecialCells dialog.

In that dialog, click the radio next to ‘Formulas’ and underneath, clear the checkboxes so that only Errors is selected. Now click OK

Excel should have selected all the cells in the worksheet with an Error (#N/A) in them.

The code below takes advantage of this trick by creating a formula in column H that will put an #N/A in all the rows you want to delete, then calling SpecialCells to find the rows, and clear (delete) them…

    Sub clearCells()
    Dim sFormula As String
    ' this formula put's an error if the test returns true, 
    ' so we can use SpecialCells function to highlight the
    ' rows to be deleted!
sFormula = "=IF(AND(A:A="""",E:E<>""""),NA(),"""")"
' put a formula into column H, to find the rows that ned to be deleted...
Range("H5:H" & Range("E65536").End(xlUp).Row).Formula = sFormula
Stop ' next line clears multiple rows, could also delete the entire row!
' now clear the cells returned by SpecialCells ...
Range("H5:H" & Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).Offset(0, -7).Clear ' ' EntireRow .Delete shift:=xlup
' clean up the formula
Range("H5:H" & Range("E65536").End(xlUp).Row).Clear    '
    End Sub

copy paste that and step through using F8 …

then we can help you some more…

Hope that gets you started

BTW, it’s also possible WITH A LOOP if you really want one 🙂



I don’t know why using loops was made out to be a bad thing by Philip. Here’s a simple macro that goes through every row and deletes rows where Column A is empty and Column E has some value.

It makes the assumption that your code is on Sheet 1. I’ve commented the code to make it easier for you to follow. If you don’t want to consider rows 1-5 for deletion, then set the For loop value to 6 as the comment in the code says.

Note that the deletion occurs from the bottom up because when you delete a row the totalRows count changes in the loop. To avoid the loop from missing rows I had it simply go in reverse order.


Public Sub DeleteWhereEmpty()
    Dim colARowCount As Integer
    Dim colERowCount As Integer
    Dim totalRows As Integer
    Dim currentRow As Integer
    Dim colA As Integer
    Dim colE As Integer
    Dim colACurrentValue As String
    Dim colECurrentValue As String

    colA = 1
    colE = 5
    colARowCount = Sheet1.Cells(Rows.Count, colA).End(xlUp).Row
    colERowCount = Sheet1.Cells(Rows.Count, colE).End(xlUp).Row

    'set total number of rows to look at
    totalRows = colARowCount
    If colARowCount < colERowCount Then
        totalRows = colERowCount 'E has more rows, so use it
    End If

    'to stop deleting at row 5, replace 'To 1' with 'To 6'
    For currentRow = totalRows To 1 Step -1
        colACurrentValue = Cells(currentRow, colA).Value
        colECurrentValue = Cells(currentRow, colE).Text

        'if A is empty and E has data in it, delete the row
        If colACurrentValue = "" Or IsEmpty(colACurrentValue) _
           And Len(colECurrentValue) > 0 Then
            Cells(currentRow, colA).EntireRow.Delete
        End If
End Sub


enter image description here


enter image description here