How to delete multiple rows without a loop in Excel VBA

前端 未结 3 1723
攒了一身酷
攒了一身酷 2020-11-28 15:27

Frequently we are asked how to delete rows based on criteria in one or more columns, and can we use a SpecialCells trick for this?

相关标签:
3条回答
  • 2020-11-28 15:59

    This will delete row numbers m to n passed through the function

    Sub Delete_Multiple_Rows (m as Integer, n as Integer) 
    
        Rows(m & ":" & n).EntireRow.Delete 
    
    End Sub
    
    0 讨论(0)
  • 2020-11-28 16:19

    Alternatively you can use auto filters:

    Sub clearCells()
    '
    ' Example code for StackOverflow post
    'http://stackoverflow.com/questions/15431801/how-to-delete-multiple-rows-without-a-loop-in-excel-vba
    '
    Dim rngTable As Range
    Dim ws As Worksheet
    Dim StartCell As Range
    
    Const ColumntoFilter1 As Integer = 1
    Const FilterCriteria1 As String = "="
    Const ColumntoFilter2 As Integer = 5
    Const FilterCriteria2 As String = "<>"
    
    Set ws = ActiveSheet
    'Set the starting position (Top-left most position) of your data range
    Set StartCell = ws.Range("A1")
    
    'Turn off autofilter in case it's already active
    ws.AutoFilterMode = False
    'Define data table
    Set rngTable = StartCell.CurrentRegion
    'Filter and delete data
    With rngTable
        .AutoFilter Field:=ColumntoFilter1, Criteria1:=FilterCriteria1
        .AutoFilter Field:=ColumntoFilter2, Criteria1:=FilterCriteria2
        .Offset(1, 0).EntireRow.Delete
    End With
    
    'Turn filters off again
    ws.AutoFilterMode = False
    
    Set rngTable = Nothing
    Set StartCell = Nothing
    Set ws = Nothing
    End Sub
    
    0 讨论(0)
  • 2020-11-28 16:23

    First, let me say categorically that there is nothing wrong with loops - they certainly have their place!

    Recently we were presented with the below situation:

    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
    

    The OP wanted to delete rows where Column A is blank, but there is a value in Column E.

    I suggest that this is an example where we could make use of SpecialCells and a temporary Error Column to identify the rows to be deleted.

    Consider that you might add a column H to try and identify those rows; in that row you could use a formula like below:

    =IF(AND(A:A="",E:E<>""),"DELETE THIS ROW","LEAVE THIS ROW")
    

    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

    =NA()
    

    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!
    

    Create a formula that will return #NA when the formula returns TRUE

    sFormula = "=IF(AND(A:A="""",E:E<>""""),NA(),"""")"
    

    Put that formula in Column H, to find the rows that are to be deleted...

    Range("H5:H" & Range("E65536").End(xlUp).Row).Formula = sFormula
    

    Now use SpecialCells to highlight the rows to be deleted:

    Range("H5:H" & Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).entirerow.select
    

    This line of code would highlight just Column A by using OFFSET in case instead of deleting the entire row, you wanted to put some text in, or clear it

    Range("H5:H" & Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).Offset(0, -7).select
    

    and the below line of code will delete thhe entire row because we can :)

    Range("H5:H" & Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Delete shift:=xlup
    
    ' clean up the formula
    Range("H5:H" & Range("E65536").End(xlUp).Row).Clear
    '
    End Sub
    

    BTW, it's also possible WITH A LOOP if you really want one :)

    One more thing, before Excel 2010 there was a limit of 8192 rows (I think because this feature went all the way back to 8-bit versions of Excel maybe)

    The VBA legend Ron de Bruin (on whose website I first picked up this technique, among others) has something to say about this

    Philip

    0 讨论(0)
提交回复
热议问题