Forum Discussion

Antonino2023's avatar
Antonino2023
Copper Contributor
May 26, 2023
Solved

VBA to delete rows whose cell in a column has length zero

Hello,

 

I'm running into an issue on a task that seems fairly simple, but is stumping me nonetheless. It is as follows:

 

In columns A-C I have an Excel Table with some rows (A7, A8, A11, A12) that are not truly empty (IsEmpty() will not return True on them). Instead, their cell value is ="". That is the result of the cell formula = IF(D2 = 1, "", "Error"). What I want to accomplish is the table shown on the right (columns E-G). I have tried the following code:

Sub TestDeleteRow()
Dim wb As Workbook
Dim ws As Worksheet
Dim tblTest As ListObject
Dim ChildNumColumn As Range
Dim TotRows As Long
Dim cell As Range

Set wb = ThisWorkbook
Set ws = wb.Worksheets("Test")
Set tblTest = ws.ListObjects("Test_T")

' Define the table column Data Body Range where we will be checking if the cell's length is 0
Set ChildNumColumn = tblTest.ListColumns("Child #").DataBodyRange

For Each cell In ChildNumColumn.Cells
    If Len(cell.Value) = 0 Then
    cell.EntireRow.Delete
    End If
Next cell

End Sub

 It does not appear to work since the following error is thrown:

In debugging, the error comes from line 18 of the code posted above. 

 

Does anyone have suggestions for achieving my task, or pointers to where my error is coming from?

 

  • HansVogelaar's avatar
    HansVogelaar
    May 26, 2023

    Antonino2023 

    How about

    Sub TestDeleteRow()
        Dim wb As Workbook
        Dim ws As Worksheet
        Dim tblTest As ListObject
        Dim ChildNumColumn As Range
        Dim LastRow As Long
        Dim i As Long
        
        Set wb = ThisWorkbook
        Set ws = wb.Worksheets("Test")
        Set tblTest = ws.ListObjects("Test_T")
        
        ' Define the table column Data Body Range where we will be checking if the cell's length is 0
        Set ChildNumColumn = tblTest.ListColumns("Child #").DataBodyRange
        
        LastRow = ChildNumColumn.Rows.Count
        
        For i = LastRow To 1 Step -1
            If Len(ChildNumColumn.Cells(i).Value) = 0 Then
                tblTest.ListRows(i).Delete
            End If
        Next i
    End Sub

8 Replies

  • NikolinoDE's avatar
    NikolinoDE
    Gold Contributor

    Antonino2023 

    The runtime error 1004 occurs because you are modifying the range while iterating through it in the loop. Deleting rows inside the loop changes the number of rows in the range, causing the runtime error.

    To overcome this issue, you can loop through the cells in reverse order, starting from the last cell and moving upwards. Deleting rows from the bottom up ensures that the row deletions do not affect the loop.

    Here's an updated version of your code that uses a reverse loop to delete rows with empty cells in the "Child #" column:

    Sub TestDeleteRow()
        Dim wb As Workbook
        Dim ws As Worksheet
        Dim tblTest As ListObject
        Dim ChildNumColumn As Range
        Dim LastRow As Long
        Dim i As Long
        
        Set wb = ThisWorkbook
        Set ws = wb.Worksheets("Test")
        Set tblTest = ws.ListObjects("Test_T")
        
        ' Define the table column Data Body Range where we will be checking if the cell's length is 0
        Set ChildNumColumn = tblTest.ListColumns("Child #").DataBodyRange
        
        LastRow = ChildNumColumn.Rows.Count
        
        For i = LastRow To 1 Step -1
            If Len(ChildNumColumn.Cells(i).Value) = 0 Then
                ChildNumColumn.Cells(i).EntireRow.Delete
            End If
        Next i
    End Sub

     

    By iterating through the cells in reverse order, the loop won't be affected by the row deletions, and it will correctly delete the rows where the cell in the "Child #" column has a length of zero.

    • Antonino2023's avatar
      Antonino2023
      Copper Contributor

      NikolinoDE 

      Thank you for the explanation! The code changes make sense, but I used your code and received the same error "Delete method of Range class failed".

      • HansVogelaar's avatar
        HansVogelaar
        MVP

        Antonino2023 

        How about

        Sub TestDeleteRow()
            Dim wb As Workbook
            Dim ws As Worksheet
            Dim tblTest As ListObject
            Dim ChildNumColumn As Range
            Dim LastRow As Long
            Dim i As Long
            
            Set wb = ThisWorkbook
            Set ws = wb.Worksheets("Test")
            Set tblTest = ws.ListObjects("Test_T")
            
            ' Define the table column Data Body Range where we will be checking if the cell's length is 0
            Set ChildNumColumn = tblTest.ListColumns("Child #").DataBodyRange
            
            LastRow = ChildNumColumn.Rows.Count
            
            For i = LastRow To 1 Step -1
                If Len(ChildNumColumn.Cells(i).Value) = 0 Then
                    tblTest.ListRows(i).Delete
                End If
            Next i
        End Sub

Resources