Excel VBA删除for循环中的行时错过了行

时间:2017-04-17 15:10:17

标签: excel vba excel-vba

我有一个子程序,可以删除包含大约1000行的范围内的行。 在critera上删除行。 以下代码有效。

但是,当我运行宏时,我通常必须运行它4次才能删除包含删除条件的所有行。

我想这是因为当一行在删除行时突然消失时,for循环错过了它的索引。

我的第一个代码看起来像这样。

    Set StatusRange = Range("B2", Range("B2").End(xlDown))

        For Each StatusCell In StatusRange
                    If StatusCell = "FG" Then
                        StatusCell.EntireRow.Delete
                    ElseIf StatusCell = "QC" Then
                        StatusCell.EntireRow.Delete
                    ElseIf StatusCell = "CS" Then
                        StatusCell.EntireRow.Delete
                    Else
                End If
     Next StatusCell

当我尝试更新每个循环的范围时,它仍然无法正常工作。

Set StatusRange = Range("B2", Range("B2").End(xlDown))
     For Each StatusCell In StatusRange
            If StatusCell = "FG" Then
                StatusCell.EntireRow.Delete
            ElseIf StatusCell = "QC" Then
                StatusCell.EntireRow.Delete
            ElseIf StatusCell = "CS" Then
                StatusCell.EntireRow.Delete
            Else
        End If

        Set StatusRange = Range("B2", Range("B2").End(xlDown))
        Next StatusCell

有没有人知道这个问题?谢谢。

3 个答案:

答案 0 :(得分:10)

从下往上工作。如果删除一行,一切都会向上移动,并在下一次迭代时跳过该行。

以下是从底部开始处理的代码的“内脏”。

With Worksheets("Sheet1")
    For rw = .Cells(.Rows.Count, "B").End(xlUp).Row To 2 Step -1
        Select Case UCase(.Cells(rw, "B").Value2)
            Case "FG", "QC", "CS"
                .Rows(rw).EntireRow.Delete
        End Select
    Next rw
End With

答案 1 :(得分:3)

在删除行之前,等待For Each循环结束:

Option Explicit

Sub mySub()

    Dim myRange As Range
    Set myRange = ActiveSheet.UsedRange

    Dim myCell As Range
    Dim myTrash As Range

    For Each myCell In myRange
        Select Case myCell.Value
            Case "my value"
                If myTrash Is Nothing _
                    Then
                        Set myTrash = myCell.EntireRow
                    Else
                        Set myTrash = Union(myTrash, myCell.EntireRow)
                End If
        End Select
    Next

    If Not myTrash Is Nothing Then myTrash.Delete

End Sub

答案 2 :(得分:2)

由于For Each没有反向循环,因此您需要使用稍微不同的方法。

此外,您的代码包含多个IfOR,并且会因使用Select Case而尖叫。

Dim StatusRange As Range
Dim i As Long

Set StatusRange = Range("B2", Range("B2").End(xlDown))

' loop backward when deleting Ranges, Rows, Cells
For i = StatusRange.Rows.Count To 1 Step -1
    Select Case StatusRange(i, 1).Value
        Case "FG", "QC", "CS"
            StatusRange(i, 1).EntireRow.Delete
        Case Else ' for the future if you need it

    End Select
Next i