根据列中的条件删除行

时间:2012-07-19 13:36:59

标签: excel vba excel-vba excel-2007

我在网上和这里搜索过,但找不到任何符合法案和工作的东西。我有一些代码可以工作,但因为它删除行时范围的长度发生变化,它没有捕获所有要删除的行,所以我最终运行了几次,这不是很好......所以我'我现在按照这个帖子的建议尝试AutoFilter方法。

我有一个包含多个列的电子表格,其中一个是“费用”。我需要浏览'cost'列(有时可以是第9列,有时是10,因此下面是'find'位)并删除成本为0的任何行...

以下是我到目前为止编写的代码,任何帮助都会非常非常赞赏!!!!

- 编辑3:已经进行了一些更改代码...新代码如下。

Sub RemoveRows()
    Dim cell As Range
    Dim lastRow As Long
    Dim lastColumn As Integer
    Dim criteraColumn As Integer
    Dim criteriaRange As Range

    lastRow = Cells.Find(What:="*", After:=Range("A1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).row
    lastColumn = Cells.Find(What:="*", After:=Range("A1"), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column

    Rows(1).EntireRow.Select
    criteriaColumn = Selection.Find(What:="Cost", After:=ActiveCell, LookIn:= _
                        xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
                        xlNext, MatchCase:=False, SearchFormat:=False).Column
    Set criteriaRange = Range("A1", Cells(lastRow, lastColumn))

    criteriaRange.AutoFilter Field:=criteriaColumn, Criteria1:="£0.00"
    AutoFilter.Range.Delete
    ActiveSheet.AutoFilterMode = False
End Sub

当我运行它时,它会将过滤器应用于正确的范围和正确的列。然后我收到错误消息:“运行时错误'424':对象必需”,适用于AutoFilter.Range.Delete行。当我按下“结束”或“调试”并查看电子表格时,过滤器已应用于正确的列并检查了正确的选项(£0.00),但没有返回结果(我知道我需要做在将来出现这种情况时会有一些错误处理,但是现在这个过滤器应该返回至少10行。如果我在电子表格中的过滤器设置上手动按“确定”(不更改它们中的任何一个!),我的10个结果会正确显示,所以我不确定为什么当我以编程方式执行此操作时它们没有出现?

如果需要,很高兴提供电子表格示例,这真让我感到困惑!!

可以找到电子表格here

4 个答案:

答案 0 :(得分:5)

您应该可以使用Excel AutoFilter删除行。

Cells.AutoFilter Field:=criteriaColumn, Criteria1:="£0.00"
ActiveSheet.AutoFilter.Range.Offset(1).Delete
ActiveSheet.ShowAllData

这将过滤cost = 0,然后删除与过滤器匹配的所有行。

操作符自动等于,因此您不需要“=£0.00”作为参数。

我在AutoFilter的ActiveSheet中添加了删除未找到的对象,而Offset使其不删除标题。

答案 1 :(得分:2)

出于性能原因,我会以另一种方式进行(读取+逐行删除很慢)。 我之前回答了类似的问题,我认为它也适用于你的帖子。

我建议您做什么:

  • 不是逐行读取工作表,而是将整个范围加载到数组中一次;
  • 不是逐行删除,而是将所需的值传输到内存中的第二个数组中;
  • 获得所需数据后,应用oRange.clearcontents清除当前范围;
  • 通过应用oRange = vArray将新数据数组显示到工作表中。

读取/转换数据在存储器中执行,读取和写入仅执行一次。

在这个帖子中,你有我之前写过的代码: Execution of VBA code gets slow after many iterations

如果这可以帮助您,或者您希望收到更具体的信息/代码,请告诉我。

答案 2 :(得分:1)

您需要做的是向后退一下该范围,因为默认情况下删除行会自动将行向上移动一行。

替换:

   For Each cell In criteriaRange.Cells
        If cell.Value = 0 Then
            cell.EntireRow.Delete
        End If
    Next cell

使用:

Dim i As Integer

For i = criteriaRange.Rows.Count To 1 Step -1
    If criteriaRange.Cells(i) = 0 Then
        criteriaRange.Cells(i).EntireRow.Delete
    End If
Next

此外,ScreenUpdating对宏的方法没有影响。它基本上会关闭宏所采取的每个动作的“屏幕闪烁”,使其更快,更顺畅地为用户体验。

答案 3 :(得分:0)

你可以这么做,只要它删除一行,它就会返回到列的顶部,或者你可以从计数中减去一行。无论哪种方式,它都不会跳过任何行。我提供了实际的代码,但我是VBA的新手,并且不太清楚如何做到这一点。