Monday, September 14, 2009

Deleting Rows in Excel with VBA

Deleting and shifting Rows up in VBA is a straightforward task that nevertheless hides a few traps. Say, any Row that has a numeric value in Column 'A' needs to be deleted and the Rows below shifted up. A VBA solution such as the one that follows does not work.

Option Explicit 

Sub DeleteRows()
Dim LastRow, Ctr As Long  

'// find the last Row with data
    LastRow = Cells(65536, 1).End(xlUp).Row

'// loop through the Rows, deleteing Rows that have a
    '// numberic value in Column 'A' and shifting Rows up   

    For Ctr = 1 To LastRow
        If IsNumeric(Cells(Ctr, 1)) Then
            Cells(Ctr, 1).EntireRow.Delete Shift:=xlShiftUp
        End If
    Next Ctr
End Sub 

The problem is that if two or more consecutive Rows have numeric values in Column 'A', not all the Rows that need to be deleted get deleted. Why? Say that Rows 3 and 4 have numeric values in Column 'A'. When Row 3 is deleted, Row 4 moves up to take its place, in effect becoming Row 3. Meanwhile, the loop counter gets incremented in the next pass from 3 to 4, with the code scanning the value in Cell A4 but inadvertently skipping the value in Cell A3. 

An elegant solution to this problem is to start looping at the last Row with data in the Worksheet and move up one Row at a time, deleting and shifting Rows up when the required condition is satisfied. Here is the solution: 
Option Explicit 

Sub DeleteRows()
    Dim LastRow, Ctr As Long   

    '// find the last row with data
    LastRow = Cells(65536, 1).End(xlUp).Row   

    '// loop through the Rows, deleteing Rows that have a
    '// numberic value in Column 'A' and shifting Rows up    

    For Ctr = LastRow To 1 Step -1
        If IsNumeric(Cells(Ctr, 1)) Then
            Cells(Ctr, 1).EntireRow.Delete Shift:=xlShiftUp
        End If
    Next Ctr 
End Sub

No comments:

Post a Comment