Home » excel » excel – Most Efficient Method for Removing Rows with Two Conditions

excel – Most Efficient Method for Removing Rows with Two Conditions

Posted by: admin May 14, 2020 Leave a comment

Questions:

What I’m trying to do is to remove rows in my spreadsheet that have values of 0 in two separate columns, as this indicates that there is no useful data in that row. While it is possible to use a For loop with If/Then conditions, I’ve found that this is incredibility slow because my dataset has ~51,000 rows andit will literally take hours, if not days, to run.

After some searching, I came across an alternate method, that I believe to be faster and am currently using:

Public Sub deleteRows()
     ' source: http://www.ozgrid.com/forum/showthread.php?t=64364
    Dim lastRow As Long
    Dim n As Long
    Dim RT As Date
    RT = Time

    With ActiveSheet
        lastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
    End With

    For n = lastRow To 2 Step -1
        If (Trim(ActiveSheet.Cells(n, 3).Value) = 0) And (Trim(ActiveSheet.Cells(n, 6).Value) = 0) Then
            ActiveSheet.Cells(n, 1).EntireRow.Delete
        End If
    Next n
    MsgBox Format(Time - RT, "hh:mm:ss")
End Sub

However, I ran a test with only 1000 cells, and it took 402 seconds to run, which indicates it would take 5.584 hours to run all of the data at the same rate.

Is there any way to speed up the process? Am I missing something obvious?

*Edit: This code is running as a subpart of another code, where ScreenUpdating = False is declared in the beginning of the code.

How to&Answers:

Here’s an approach using autofilter:

Public Sub deleteRows()
    Dim lastRow As Long
    Dim rng As Range
    Dim start

    start = Timer
    With ActiveSheet
        .AutoFilterMode = False
        lastRow = .Cells(.Rows.Count, 2).End(xlUp).Row
        '~~> Set the range of interest, no need to include the entire data range
        Set rng = .Range("B2:F" & lastRow)
        rng.AutoFilter 2, 0 '~~> filter zeros on C column
        rng.AutoFilter 5, 0 '~~> filter zeros on F column
        '~~> Delete the entire row of the remaining visible cells
        rng.Offset(1, 0).Resize(rng.Rows.Count - 1) _
            .SpecialCells(xlCellTypeVisible).EntireRow.Delete
        .AutoFilterMode = False
    End With
    Debug.Print (Timer - start) * 1000 '~~> in ms
End Sub

Tried and tested on sample data (Cell B2:L52802).
The deleting took 11699.22 ms or roughly 11.7 seconds in my machine.
I think that’s fast enough compared to your estimated 5 hours (1700 times faster to be specific).

Answer:

Nah, it would actually take even longer. If you delete a row, every single row below it will be moved up individually, which obviously takes longer if there are more rows below the one you are deleting.

Here are a couple simple ways of doing it:

  1. Using AutoFilter to filter for the undesired rows and then deleting the visible cells.

  2. Using AutoFilter to filter for the rows you want to keep and copy those to a new workbook.

  3. Sort the values first, so that all the undesired rows are at the bottom. You are allready deleting from the bottom up so you’d just have to insert a sort in front of your loop.