Reputation: 1391
I have a table tbl
which is a ListObject
. I want to delete rows that only have empty values or equations.
Dim tbl As ListObject
Set tbl = sh.ListObjects(1)
Dim r As ListRow
Dim c As Range
Dim d As Integer
For Each r In tbl.ListRows
d = 1
For Each c In r.Range.Cells
If IsEmpty(c) = False And c.HasFormula = False Then
d = 0
End If
Next
If d = 1 Then
Debug.Print "DELETE", r.Index
'''' rows(r.Index).EntireRow.Delete
End If
Next
This works until I uncomment the commented line which deletes the row.
Probably some objects get messed up upon deletion, because error says:
Application defined or object defined error.
Upvotes: 0
Views: 167
Reputation: 1870
See my recommendation here that is more modular and deletes very fast https://stackoverflow.com/a/73322827/1279373
Upvotes: 0
Reputation: 7627
Solution without nested loop:
Option Explicit
Sub test1()
Dim tbl As ListObject, i As Long, x As Range
Set tbl = sh.ListObjects(1)
For i = tbl.ListRows.Count To 1 Step -1
Set x = Nothing
On Error Resume Next
Set x = tbl.ListRows(i).Range.SpecialCells(xlCellTypeConstants) 'not empty and not formulas
On Error GoTo 0
If x Is Nothing Then
Debug.Print "DELETED " & i
tbl.ListRows(i).Delete
End If
Next
End Sub
Upvotes: 0
Reputation: 12167
The other solution would be, as always, to step backwards through the rows
Sub loDel()
Dim tbl As ListObject
Set tbl = sh.ListObjects(1)
Dim d As Integer
Dim i As Long
Dim c As Range
For i = tbl.ListRows.Count To 1 Step -1
d = 1
Dim rg As Range
Set rg = tbl.ListRows(i).Range
For Each c In rg
If IsEmpty(c) = False And c.HasFormula = False Then
d = 0
End If
Next
If d = 1 Then
Debug.Print "DELETE", i
tbl.ListRows(i).Delete
End If
Next
End Sub
Upvotes: 1
Reputation: 12167
As suggested in one of the comments one could collect the rows to be deleted
Sub loDel()
Dim tbl As ListObject
Set tbl = sh.ListObjects(1)
Dim r As ListRow
Dim c As Range
Dim d As Integer
Dim dRg As Range
For Each r In tbl.ListRows
d = 1
For Each c In r.Range.Cells
If IsEmpty(c) = False And c.HasFormula = False Then
d = 0
End If
Next
If d = 1 Then
Debug.Print "DELETE", r.Index
If dRg Is Nothing Then
Set dRg = r.Range
Else
Set dRg = Union(dRg, r.Range)
End If
'Rows(r.Index + 1).EntireRow.Delete
End If
Next
If Not dRg Is Nothing Then
dRg.Rows.Delete
End If
End Sub
Upvotes: 1