删除行在指定的单元格中的行

For Each c In oSheet.Range("A1:A1000") If InStr(c.Value, "VALUE") Then c.EntireRow.Delete() End If Next 

这只会删除指定范围内的一些行,问题是什么?

以下是根据条件删除整行的两种常见模式。 主要思想是在迭代时不能从集合中删除 。 这意味着Delete不应该出现在For Each这在大多数编程语言中都是相当标准的,有些甚至会抛出一个错误来阻止它。

选项1 ,使用整数来跟踪行并使其从结尾到开始工作。 您需要后退,因为这是避免跳过行的简单方法。 有可能前进,你只需要考虑在你删除时不递增。

 Sub DeleteRowsWithIntegerLoop() Dim rng_delete As Range Set rng_delete = Range("A1:A1000") Dim int_start As Integer int_start = rng_delete.Rows.Count Dim i As Integer For i = int_start To 1 Step -1 If InStr(rng_delete.Cells(i), "VALUE") > 0 Then rng_delete.Cells(i).EntireRow.Delete End If Next i End Sub 

选项2 ,使用Union-Delete模式来build立一系列的单元格,然后在最后一步删除它们。

 Sub DeleteRowsWithUnionDelete() Dim rng_cell As Range Dim rng_delete As Range For Each rng_cell In Range("A1:A1000") If InStr(rng_cell, "VALUE") > 0 Then If rng_delete Is Nothing Then Set rng_delete = rng_cell Else Set rng_delete = Union(rng_delete, rng_cell) End If End If Next rng_delete.EntireRow.Delete End Sub 

关于代码的说明

对于选项2,还有一个额外的条件是在第一项开始时创buildrng_deleteUnion不能使用Nothing引用,所以我们先检查一下,如果是的话, Set为第一项。 所有其他人通过Union线路获得Set

偏爱

在两者之间进行select时,我总是比较喜欢选项2,因为我更喜欢在Excel中使用Ranges ,而不是使用计数器遍历Cells 。 这是有限制的。 第二个选项也适用于不连续的Ranges和所有其他各种各样的怪异Ranges (例如,在对SpecialCells的调用之后),当你不确定你将要处理什么数据时,这可以使它有价值。

速度

我不确定速度比较。 如果ScreenUpdating和计算启用,两者都可能会变慢。 第一种select使得N-1呼叫Delete而第二种select做一个。 Delete是一个昂贵的操作。 然而,选项2不会对UnionSet进行N-1呼叫。 我认为它比第一个基于(这似乎在这里),但我没有configuration文件。

最后说明: InStr返回一个整数,指示find值的位置。 我总是喜欢在这里显式布尔covnersion,并比较>0

不要使用循环,使用诸如AutoFilter的方法

 Sub Recut() Dim ws As Worksheet Dim rng1 As Range Set ws = ActiveSheet Set rng1 = ws.[A1:A100] ws.AutoFilterMode = False Application.ScreenUpdating = False With rng1 .AutoFilter Field:=1, Criteria1:="*VALUE*" `assuming A1 is a header, and checking for at least 1 match on the filtered string If .SpecialCells(xlCellTypeVisible).Cells.Count > 1 Then .Offset(1, 0).Resize(rng1.Rows.Count - 1, 1).EntireRow.Delete End With ws.AutoFilterMode = False Application.ScreenUpdating = True End Sub