VBA使用Like运算符删除行

时间:2018-10-04 01:25:51

标签: excel vba for-loop

简单的事情并不简单。我试图基于具有以“ 2L”开头的数据的特定列删除行。所以我写了这段代码(LastRow被理解):

Sub Cleanup()

For i = 1 To LastRow
    If Range("F" & i) Like "2L*" Then Rows(i).delete
Next i
End Sub

问题在于它确实删除了行。我不知道删除行的标准是什么,但我知道在编写该列时,它不会获得每一行都以“ 2L”开头的单元格。我从1100行开始,然后下降到677。

我没有创建要编写脚本的excel。唯一的提示是,我确实尝试设置列的格式,并且当格式窗口打开时,它们没有单一类型。在将代码运行为Text之前,我确实尝试过格式化数据列,但似乎并没有解决问题。

有想法吗?

3 个答案:

答案 0 :(得分:5)

首先,一些强制性的房屋保管.....

  1. 添加Option Explicit
  2. 添加Option Explicit
  3. 使用工作表限定所有对象(Range

出于某些原因,应避免在循环时删除行。主要原因是它可能效率很低。举例来说,假设您有500个Like "2L*"单元格。这意味着您将删除500行迭代。

相反,将Like "2L*"的每个实例添加到单元格的Union(集合)中,一旦循环完成,请删除整个Union一旦。现在您只有1个行实例被删除。

避免在循环中删除行的另一个原因是它迫使您向后循环。这没有什么错,因为一开始并不直观,它只会给人们带来麻烦。删除行时,您向上移动要循环的范围,这将导致跳过行。下面的方法不需要向后循环。


Option Explicit

Sub Cleanup()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("???")
Dim i As Long, DeleteMe As Range

'Gather up union of CELLS like 2L*
For i = 1 To ws.Range("F" & ws.Rows.Count).End(xlUp).Row
    If ws.Range("F" & i) Like "2L*" Then
        If DeleteMe Is Nothing Then
            Set DeleteMe = ws.Range("F" & i)
        Else
            Set DeleteMe = Union(DeleteMe, ws.Range("F" & i))
        End If
    End If
Next i

'Delete collection of cells here (if any exist)
If Not DeleteMe Is Nothing Then DeleteMe.EntireRow.Delete

End Sub

出于学习目的,这是您将向后循环的方式。它的行数少于上述方法,但效率较低。如果您决定走这条路,请务必关闭ScreenUpdating以加快速度

Sub CleanUp2()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("???")
Dim i As Long

For i = ws.Range("F" & ws.Rows.Count).End(xlUp).Row to 1 Step -1 '<===== Backwards!
    If ws.Range("F" & i) Like "2L*" Then ws.Rows(i).Delete
Next i

End Sub

答案 1 :(得分:1)

或使用自动过滤器

Option Explicit
Public Sub CleanUp()
    Dim lastRow As Long, testRange As Range
    With ThisWorkbook.Worksheets("Sheet2")
        lastRow = .Cells(.Rows.Count, "F").End(xlUp).Row
        Set testRange = .Range("F1:F" & lastRow)
        If Application.WorksheetFunction.CountIf(testRange, "2L*") > 0 Then
            With testRange
                .AutoFilter
                .AutoFilter Field:=1, Criteria1:="2L*", Operator:=xlFilterValues
                .SpecialCells(xlCellTypeVisible).EntireRow.Delete
            End With
        End If
    End With
End Sub

答案 2 :(得分:0)

我将在这里borrow from Jeeped并提供不需要循环的答案:

Sub DeleteBlankRows()

    With Worksheets(1)
        On Error Resume Next
        Intersect(.Range("F:F"), .UsedRange).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
        On Error GoTo 0
    End With

End Sub