在列中匹配条件后,删除excel表中的行

时间:2015-11-22 15:07:18

标签: excel vba editor rows

我的数据看起来像这样。

enter image description here

我想删除名为Position from first的值中的值为1的行。我写了一个宏来做这样的事情

Sub DEL_row()
row_number = 2

Do
DoEvents

row_number = row_number + 1
Position_from_first = Sheet8.Range("E" & row_number)

If InStr(Position_from_first, "1") >= 1 Then

Sheet8.Rows(row_number & ":" & row_number).Delete

End If

Loop Until Position_from_first = ""

MsgBox "completed"

End Sub

但是当我运行它时,我收到一个错误。 msg框说完了,但是当我浏览excel表时它没有完成所需的工作。 任何人都可以帮我解决问题所在。

非常感谢帮助...

2 个答案:

答案 0 :(得分:2)

虽然您的概念很明显,但您的语法和对VBA的理解存在一些错误。我在下面列出了它们。

  1. 根本不需要在此代码中执行任何事件。
  2. 删除行时,您需要从最后一行开始并在循环中返回到开头,因为当您删除行时它会影响下面的所有行引用,因此如果您的循环计数将丢失行,则你往前走
  3. 您还需要使用.DeleteSub DEL_row() 'get last used row in column E row_number = Sheet8.Range("E" & Sheet8.Rows.Count).End(xlup).Row For x = row_number to 2 Step -1 Position_from_first = Sheet8.Range("E" & row_number) If InStr(Position_from_first, "1") >= 1 Then 'If Sheet8.Range("E" & row_number) = 1 ' this will also work Sheet8.Rows(row_number & ":" & row_number).EntireRow.Delete End If Next MsgBox "completed" End Sub 只会删除单元格内容。
  4. 我已修复下面的代码以反映这些问题。我还提供了一个更简单的替代方案来解决您使用AutoFilter方法的问题。

    Sub DEL_row()
    
    With Sheet8
    
       'get last used row in column E
        row_number = .Range("E" & .Rows.Count).End(xlup).Row
    
        With .Range("E1:E" & row_number)
    
             .AutoFilter 1, "1"
             .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
    
        End With
    
        .AutoFilterMode = False
    
    End With
    
    Msgbox "completed"
    
    End Sub
    

    如果你使用AutoFilter,你可以完全避免循环(并节省时间),如下所示:

    document.getSelection()

答案 1 :(得分:1)

我认为您不想删除 11,12,31,... 等,因此使用InStr function不是识别要删除的正确行的适当方法。您的示例数据图像将E列显示为具有真正的右对齐数字,Range.Value2 property可以直接与 1 进行比较,以确定是否应删除该行。

如上所述,删除行时,从底部到顶部工作非常重要。如果你从上到下工作,你可能会在删除一行时跳过一行,一切都会向上移动,然后你会增加到下一行。

Option Explicit

Sub DEL_1_rows()
    'declare your variables
    Dim rw As Long

    'this will greatly improve the speed involving row deletion
    Application.ScreenUpdating = False

    With sheet8   '<~~ this is a worksheet CodeName - see below
        For rw = .Cells(Rows.Count, 5).End(xlUp).Row To 2 Step -1
            If .Cells(rw, 5).Value2 = 1 Then .Rows(rw).EntireRow.Delete
        Next rw
    End With

    Application.ScreenUpdating = True

    MsgBox "completed"

End Sub

AutoFilter Method可以加快识别要删除的行。但是,单个大批量删除仍然需要大量的处理时间。

Option Explicit

Sub DEL_Filtered_rows()

    'this will greatly improve the speed involving row deletion
    Application.ScreenUpdating = False

    With Sheet8   '<~~ this is a worksheet CodeName - see below
        If .AutoFilterMode Then .AutoFilterMode = False
        With .Range(.Cells(1, 5), .Cells(Rows.Count, 5).End(xlUp))
            .AutoFilter field:=1, Criteria1:=1
            With .Resize(.Rows.Count, .Columns.Count).Offset(1, 0)
                If CBool(Application.Subtotal(103, .Cells)) Then
                    .SpecialCells(xlCellTypeVisible).EntireRow.Delete
                End If
            End With
            .AutoFilter
        End With
    End With

    Application.ScreenUpdating = True

    MsgBox "completed"

End Sub

我发现使用工作表.CodeName property而不是工作表.Name property识别工作表有点奇怪。我已经包含了几个链接,以确保您正确使用命名约定。无论如何,我使用With ... End With statement来避免重复识别父工作表。