VBA:删除具有特定值的行

时间:2012-04-09 17:25:45

标签: vba excel-vba delete-row excel

我正在尝试编写一个宏来删除A列中“True”的所有行。

这是我到目前为止所做的:

Sub deleteBlankRows3()
Dim lastrow as Long
Dim x as Long

lastrow = 4650
For x=8 to x=lastrow
    If (Range("A1").Offset(x,0) = True) Then
    Range("A1").Offset(x,0).EntireRow.Delete
    x = x + 1
End if
Next x

End Sub

我不知道出了什么问题!

5 个答案:

答案 0 :(得分:7)

我知道你已经得到了你想要的东西。但是,仍然是使用Autofilter的另一种方法。这比循环遍历每一行并检查值要快得多。

Sub Sample()
    Dim lastRow As Long

    With Sheets("Sheet1")

        lastRow = .Range("A" & Rows.Count).End(xlUp).Row

        '~~> Remove any filters
        .AutoFilterMode = False

        '~~> Filter, offset(to exclude headers) and delete visible rows
        With .Range("A1:A" & lastRow)
            .AutoFilter Field:=1, Criteria1:="TRUE"
            .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
        End With

        '~~> Remove any filters
        .AutoFilterMode = False
    End With
End Sub

HTH

答案 1 :(得分:4)

这里可能有三件事情在起作用。

首先,如果您正在测试基础值的等效性,那么您应该明确地查看单元格的值:

If (Range("A1").Offset(x,0).Value = True) Then

不用说。值得,我认为默认情况下,单元格返回它的Text属性,用于对非范围属性进行等价测试。

其次,您的单元格可能包含字符串“True”,而不是值True所以请尝试使用

If (Range("A1").Offset(x,0).Value = "True") Then

最后,如果你实际找到一行,然后删除它,那么你实际上最终会跳过一行,因为删除行之后的所有行都将向下移动(第5行变为第4行等),但是你只增加了x,所以你将在删除的每一行之后立即跳过该行。要解决此问题,请按递减顺序循环:

For x=lastrow to 8 step -1

如果您刚刚删除了一行,则不要递增x:

If (Range("A1").Offset(x,0).Value = "True") Then
    Range("A1").Offset(x,0).EntireRow.Delete
Else
    x = x + 1
EndIf

答案 2 :(得分:2)

如果没有测试,你最好这样:

    For x=lastrow to 8 step -1
        If (Range("A1").Offset(x,0) = True) Then 
           Range("A1").Offset(x,0).EntireRow.Delete 
        End if 
   Next

计数有一个问题,如果你在向上移动后删除一行所有行,导致你的循环不能查看所有行。而且,由于在这些情况下你将x加1,你就会变得更糟。 -1会更好,除了你仍然检查4650 + number_of_deleted_rows总计可能导致其他问题。通过从最后开始并向开始前进,您可以防止这两个问题。

答案 3 :(得分:1)

问题是算法不正确。损坏的循环变量的经典案例。问题是循环所依赖的变量会被修改,因此它是错误的。

这样做的正确方法就是这样。

Dim x as integer
x = 8
do
   if (Range("a1").Offset(x, 0) = True) Then
       Range("a1").Offset(x, 0).EntireRow.Delete
   Else
       x = x + 1 'We only increase the row number in the loop when we encounter a row that is false for containing true in cell a1 and their offsets
   End If
Loop Until (x > 4650)

答案 4 :(得分:0)

我有隐藏的线条,并且不想取消隐藏过滤方法所做的操作。 也不想遍历每一行所以这里是我的10c .....

Sub DelError()
    Dim i As Integer
    Dim rngErrRange As Range
    With ActiveSheet
        Do
            Set rngErrRange = .Columns("A:A").Find(What:="#REF!", _
                After:=.Cells(1), LookIn:=xlFormulas, _
                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False)
                If Not rngErrRange Is Nothing Then
                    rngErrRange.EntireRow.Delete
                Else
                    End
                End If
        Loop
    End With
End Sub