Home » excel » excel – Delete "unioned" non-contiguous range

excel – Delete "unioned" non-contiguous range

Posted by: admin May 14, 2020 Leave a comment


I can’t use rng.EntireRow.Delete when the range is non-contiguous, and the range is built by Union.

  1. I know that I can delete multiple rows based on criteria by using sort and autofilter. I want to learn something new. I am not interested in backwards deleting or using loops, it’s too time consuming.
  2. The code fails when the range “usun” is non-contiguous.
  3. While debugging: range “usun.Address” seems to be building correctly e.g. “$E$10:$E15,$E$20,$E$30:$E$32”
Sub delSomeRows()

    Set tbl = ThisWorkbook.Sheets("test").ListObjects(1)
       ' formulas into values
        tbl.DataBodyRange.Value = tbl.DataBodyRange.Value 

    ' Get the column reference to analysis
       Dim komorka      ' cell to be analysed
       Dim usun As Range    ' multiple ranges to delete
       Dim filter As Range  ' column in the table
       Set filter = tbl.ListColumns("Filtr").DataBodyRange

    ' Get Union range to delete
       For Each komorka In filter
           If Len(komorka.Value) <> 0 Then
                If usun Is Nothing Then
                    Set usun = komorka
                    Set usun = Application.Union(usun, komorka)
                End If
           End If
        Next komorka

    ' delete all rows at once
        usun.EntireRow.Delete ' ERROR 1004 HERE

End Sub

I am trying to delete some rows e.g. second, third and sixth or others at once using EntireRow.Delete on “Unioned” range.

How to&Answers:

You are trying to delete table rows like this:

non-contiguous entire sheet rows selected

Excel won’t let you delete non-contiguous entire sheet rows when a table /listobject is involved – either programmatically or through the UI (well, at least from the context menu – works from the Home Ribbon tab for some reason).

What you want to do is this:

listrows are selected; non-contiguous deletion works

You can’t delete sheet rows, but now Excel understands what we’re trying to achieve. The trick is to get this selection programmatically.

Iterate the ListObject‘s ListRows instead, and Union the ListRow.Range; the unioned resulting range’s Delete method will then work (don’t use .EntireRow).

This worked for my dummy table, from the immediate pane:


So with your code, I’d iterate tbl.ListRows and Union the ListRow.Range items – not tested, but this should work:

Dim filterColumn As Long
filterColumn = tbl.ListColumns("Filtr").Index

Dim currentRow As ListRow
For Each currentRow In tbl.ListRows
    If Len(currentRow.Range.Cells(ColumnIndex:=filterColumn).Value) <> 0 Then
        If usun Is Nothing Then
            Set usun = currentRow.Range
            Set usun = Application.Union(usun, currentRow.Range)
        End If            
    End If

If Not usun Is Nothing Then usun.Delete