How do I ignore the first row in an Excel macro that deletes all rows based on a criteria?

后端 未结 3 1155
终归单人心
终归单人心 2020-12-02 02:54

This macro is designed to compare the data in column C and D and if C does not match D in a certain row, it deletes the entire tow. The problem is that it deletes the header

相关标签:
3条回答
  • 2020-12-02 03:18

    you can avoid loops:

    Sub deleteNonMatchingRows()
        With Range("C2", Cells(Rows.Count, "C").End(xlUp)) ' reference column C cells from row 2 doen to last not empty one
            With .Offset(, .Parent.UsedRange.Columns.Count) ' reference referenced range offset by active sheet used range columnns (to be sure you'r not overwriting already filled cells)
                .FormulaR1C1 = "=IF(RC3<>RC4,1,"""")" ' have referenced cells show a "1" if corresponding cells in column C and D match
                .SpecialCells(xlCellTypeFormulas, xlNumbers).EntireRow.Delete ' delete all rows whose referenced column formula result is a number
                .ClearContents ' clear referenced range
            End With
        End With
    End Sub
    
    0 讨论(0)
  • 2020-12-02 03:33

    Deletion of a row is an operation that takes quite some time. Thus, it is a good idea to make all deletions at once, uniting all rows to be deleted in a specific range wholeRange:

    Option Explicit
    
    Public Sub DeleteNonMatchingRows()
    
        Dim LastRow As Long
        LastRow = Cells(Rows.Count, "C").End(xlUp).Row
    
        Dim wholeRange  As Range
        Dim iRow As Long
        For iRow = LastRow To 2 Step -1
            If Range("C" & iRow) <> Range("D" & iRow) Then
                If wholeRange Is Nothing Then
                    Set wholeRange = Rows(iRow)
                Else
                    Set wholeRange = Union(wholeRange, Rows(iRow))
                End If
            End If
        Next iRow
    
        If Not wholeRange Is Nothing Then
            wholeRange.Select       'delete this row
            Stop                    'delete this row
            wholeRange.Delete
        End If
    
    End Sub
    

    Once you run the code, it will stop on the Stop line. You will be able to see the range, which is to be deleted. The range will be selected. Once you see it, it is a good idea to delete the two rows, mentioned in the comments, you are not going to need them any more.

    0 讨论(0)
  • 2020-12-02 03:38

    If you use a descriptive variable naming, eg. rename i into iRow you will never forget that this is your row counter, that is counting from row 9999 to row 1 in For iRow = 9999 To 1 Step -1. So you need to change the 1 into a 2 to omit the first row.

    I recommend to use a dynamic start for your loop that automatically finds the last used row. This prevents unnecessary loop steps and you don't need to increase it for larger worksheets.

    Option Explicit
    
    Public Sub DeleteNonMatchingRows()
        Dim LastRow As Long
        LastRow = Cells(Rows.Count, "C").End(xlUp).Row 'find last used row in column C
    
        Dim iRow As Long
        For iRow = LastRow To 2 Step -1 
            If Range("C" & iRow) <> Range("D" & iRow) Then
                'Range("C" & iRow).EntireRow.Delete
                 Rows(iRow).Delete 'directy delete a row
            End If
        Next iRow
    End Sub
    
    0 讨论(0)
提交回复
热议问题