1

我有一个有趣的问题。我试过搜索这个网站和谷歌,但只有轻微相关的问题,没有一个真正解决这个特定需求。

我有一个包含 10 列的电子表格(我们称它们为A-J)。我需要删除"30", "60", "90", "120"H 列的单元格中没有值或空白的所有行。

尽管有很多方法可以做到这一点,但它们都依赖于循环,这对我来说不起作用,因为这个数据集有超过 25k 行并且需要 10 多分钟才能运行 - 太长了。

我一直在研究自动筛选选项和.Find函数(例如,查找所有不符合条件的 H 单元格的行并删除),但AutoFilter在 2003 年仅适用于 2 个条件,而我有 5 个要检查。我不确定如何进行。

任何帮助表示赞赏。

4

5 回答 5

2

这在 20 秒内删除了 25k 行样本中的所有匹配行 (~10%)

Sub tt()

Dim rw As Range
Dim all As Range
Dim t
Dim b As Boolean

t = Timer
For Each rw In Range("A1").CurrentRegion.Rows

    If rw.Cells(8).Value < 1 Then

        If b Then
            Set all = Application.Union(rw, all)
        Else
            Set all = rw
            b = True
        End If

    End If

Next rw

If not all is nothing then all.EntireRow.Delete

Debug.Print "elapsed: " & Timer - t

End Sub
于 2013-07-10T06:11:34.110 回答
0

您可以尝试高级过滤器选项,您可以在其中提供两个以上的条件来过滤列表。过滤与您设置的条件匹配的列表后,可以将过滤后的列表复制到另一个位置(可用选项)并将其余的删除。

于 2013-07-10T06:11:26.860 回答
0

您可以根据自己的条件添加一列:

=IF(OR(H1=30;H1=60;H1=90;H1=120;H1="");"DELETE";"")

(公式是为第 1 行给出的,您必须将其复制粘贴到整个范围内)

然后使用过滤和排序来选择要删除的行。

于 2013-07-10T06:13:19.803 回答
0

感谢所有提出解决方案的人。在此期间,我最终找到了一种在 <1 秒内完成此操作的方法——显然我自己并没有意识到这AutoFilter可以支持比较标准(大于、小于等)。

使用一系列自动过滤器,我只是对其进行了过滤,然后删除了过滤为“<30”、“30120”的所有行。

不优雅,但它成功了。

于 2013-07-11T23:01:46.677 回答
0

一些速度提示:

  1. 使用大数据时,给数组赋值,用数组代替*.Value;
  2. 使用满列时,忽略底部的空列;
  3. 在工作表中进行大量更改时,禁用屏幕更新和自动计算。

说明这一点,我将使用以下代码:

Sub Macro1()
    Dim su As Boolean, cm As XlCalculation
    Dim r As Long, v(), r_offset As Long

    su = Application.ScreenUpdating
    Application.ScreenUpdating = False 'Disable screen updating
    cm = Application.Calculation
    Application.Calculation = xlCalculationManual 'Disable automatic calculation

    'Only use used values
    With Intersect(Range("H:H"), Range("H:H").Worksheet.UsedRange)
        v = .Value 'Assign values to array
        r_offset = .Row - LBound(v) 'Mapping between array first index and worksheet row number
    End With

    'Check all row from bottom (so don't need to deal with row number changes after deletion)
    For r = UBound(v) To LBound(v) Step -1
        Select Case v(r, 1)
        Case "30", "60", "90", "120", Empty 'Do nothing
        Case Else
            Sheet1.Rows(r + r_offset).EntireRow.Delete
        End Select
    Next
    Application.ScreenUpdating = su 'Restore screen updating
    Application.Calculation = cm 'Restore calculation mode
End Sub
于 2013-07-10T08:52:00.547 回答