通过自动过滤器删除时间过长

时间:2015-12-01 19:23:24

标签: excel excel-vba vba

我有大约8000多行。使用自动过滤器删除行需要几分钟。我认为autofilter是事实上快速删除的方式(而不是逐行循环)。我怎样才能加快速度?有更快的方法吗?公平地说,一半的行被删除XD

With ThisWorkbook.Worksheets("Upload")
    lastRow = .Cells(.Rows.Count, "S").End(xlUp).Row
    Set dataRng = .Range(.Cells(4, 1), .Cells(lastRow, 19))
    dataRng.AutoFilter field:=19, Criteria1:="=0"
    Application.DisplayAlerts = False
    dataRng.Offset(1, 0).Resize(dataRng.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete
    Application.DisplayAlerts = True
    .ShowAllData
End With

2 个答案:

答案 0 :(得分:5)

我将挑战潜在的假设,即AutoFilter是快速前进的方法 - 通常很难在变量数组上击败循环

此演示显示了一种方法,在我的系统上处理8000多行,在亚秒内删除一半

Sub DEMO()
    Dim datrng As Range
    Dim dat, newdat
    Dim i As Long, j As Long, k As Long
    With ThisWorkbook.Worksheets("Upload")
        Set datrng = .Range(.Cells(1, 1), .Cells(.Rows.Count, "S").End(xlUp))
    End With
    dat = datrng.Value
    ReDim newdat(1 To UBound(dat, 1), 1 To UBound(dat, 2))
    j = 1
    For i = 1 To UBound(dat, 1)
        If dat(i, 19) <> 0 Then ' test for items you want to keep
            For k = 1 To UBound(dat, 2)
                newdat(j, k) = dat(i, k)
            Next
            j = j + 1
        End If
    Next

    datrng = newdat
End Sub

答案 1 :(得分:4)

我测试了宏的速度,发现排序,自动过滤和删除比构建数组更快。

使用时间码here我运行原始代码超过100k行随机数据(0-4之间25列宽的随机数)。

- 原始代码耗时78秒(此处只运行了5万行以加快速度)

- 克里斯提出的数组代码耗时1.91秒

- 下面的代码花了0.84秒(尝试运行它按升序和降序排序,如果零的范围被分类到顶部或底部,则没有什么区别。

我意识到内置时钟在vba中并不是很好但是差别足以让我很自然地说排序,过滤,删除至少和数组一样快。

以下代码只是将dataRng.Sort key1:=Range("S4"), order1:=xlDescending, Header:=xlYes添加到原始代码

Sub test()

With Sheets("sheet1")
    lastRow = .Range("S" & .Rows.Count).End(xlUp).Row
    Set dataRng = .Range(.Cells(4, 1), .Cells(lastRow, 25))
    dataRng.Sort key1:=Range("S4"), order1:=xlDescending, Header:=xlYes
    dataRng.AutoFilter field:=19, Criteria1:="=0"
    Application.DisplayAlerts = False
    dataRng.Offset(1, 0).Resize(dataRng.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete
    Application.DisplayAlerts = True
    .ShowAllData
End With
End Sub