使用基于列的值删除行

时间:2018-02-27 18:03:44

标签: excel vba excel-vba

我的月度基数接近373,000行。其中,部分值较低或为空白。我想删除这一行。

我有部分代码删除那些没有的代码。如何以更灵活的方式创建连接空行条件(D列)的代码。

由于

Sub DelRowsZero()

    Dim i As Long
        For i = Cells(Rows.Count, "D").End(xlUp).Row To 2 Step -1
        If Cells(i, "D") = 0 Then Rows(i).Delete
    Next i

End Sub

Example

3 个答案:

答案 0 :(得分:2)

怎么样:

Sub ZeroKiller()
    Dim N As Long, ToBeKilled As Range
    Dim i As Long

    N = Cells(Rows.Count, "A").End(xlUp).Row
    For i = 1 To N
        If Cells(i, "D").Value = 0 Or Cells(i, "D").Value = "" Then
            If ToBeKilled Is Nothing Then
                Set ToBeKilled = Cells(i, "D")
            Else
                Set ToBeKilled = Union(ToBeKilled, Cells(i, "D"))
            End If
        End If
    Next i

    If Not ToBeKilled Is Nothing Then
        ToBeKilled.EntireRow.Delete
    End If
End Sub

这假设 A 是最长的列。如果情况并非总是如此,请使用:

N = Range("A1").CurrentRegion.Rows.Count

答案 1 :(得分:2)

我担心375K线,谁知道这需要多长时间才能运行。

    Sub Button1_Click()

    Dim i As Long
    For i = Cells(Rows.Count, "D").End(xlUp).Row To 2 Step -1
        If Cells(i, "D") = 0 Or Cells(i, "D") = "" Then
            Rows(i).Delete
        End If
    Next i


End Sub

我很想知道这是否适用于其他人,它只是使用"替换" 0值为空白,然后使用特殊单元删除空行。我对38K行的测试需要3秒钟。

    Sub FindLoop()

    Dim startTime As Single
    startTime = Timer


    '--------------------------


    Columns("D:D").Replace What:="0", Replacement:="", LookAt:=xlPart, _
                           SearchOrder:=xlByRows, MatchCase:=True, SearchFormat:=False, _
                           ReplaceFormat:=False
    Columns("D:D").SpecialCells(xlCellTypeBlanks).EntireRow.Delete



    '---------------------------------
    Debug.Print Timer - startTime
End Sub

答案 2 :(得分:1)

There's apparently an argument to be made,在找到行时删除行会比一次删除行更快。

所以我在A和B列中运行了36000行=RANDBETWEEN(0, 10)下面的代码(然后复制+粘贴特殊值/值),并在32秒内完成了三次并且灰尘。

取消注释currentValue赋值并用currentValue比较替换数组下标访问会增加2.5秒的开销;取消注释IsError检查会增加另外3.5秒的开销 - 但如果选中的单元格稍有可能包含一些#REF!#VALUE!错误,则代码不会爆炸。< / p>

每次我运行它时,大约有4000行被删除。

注意:

  • 没有隐式ActiveSheet引用。该代码适用于Sheet2Worksheets("Sheet2")代码名称 - 一个全局范围的Worksheet对象变量,您可以免费获得存在于此处的任何工作表编译时间。如果您在编译时运行此表单,则使用其代码名称属性中的(Name)属性> toolwindow / F4)。
  • 范围是硬编码的。您已经知道如何获取数据的最后一行,所以我没有为此烦恼。尽管如此,您仍希望将工作范围转储到变量数组中。
  • 如果所涉及的任何单元格都没有机会包含工作表错误值,则可以忽略/删除已注释掉的代码。
Public Sub SpeedyConditionalDelete()

    Dim startTime As Single
    startTime = Timer

    '1. dump the contents into a 2D variant array
    Dim contents As Variant
    contents = Sheet2.Range("A1:B36000").Value2

    '2. declare your to-be-deleted range
    Dim target As Range

    '3. iterate the array
    Dim i As Long
    For i = LBound(contents, 1) To UBound(contents, 1)

        '4. get the interesting current value
        'Dim currentValue As Variant
        'currentValue = contents(i, 1)

        '5. validate that the value is usable
        'If Not IsError(currentValue) Then

            '6. determine if that row is up for deletion
            If contents(i, 1) = 0 Or contents(i, 1) = vbNullString Then

                '7. append to target range
                If target Is Nothing Then
                    Set target = Sheet2.Cells(i, 1)
                Else
                    Set target = Union(target, Sheet2.Cells(i, 1))
                End If

            End If

        'End If

    Next

    '8. delete the target
    If Not target Is Nothing Then target.EntireRow.Delete

    '9. output timer
    Debug.Print Timer - startTime

End Sub

当然375K行的运行时间会比32-38秒长,但我无法想到更快的解决方案。