【问题标题】:More efficient way of deleting rows更有效的删除行的方法
【发布时间】:2017-06-20 01:35:13
【问题描述】:

我有一些代码可以删除不在要保留的指定行号列表中的行。它按预期运行。

 For lRow = numRowsInBBS To 1 Step -1

    lMatch = 0
    On Error Resume Next
    lMatch = Application.Match(lRow, ws.Range("AE4:AE" & numRows).Value, 0&)
    On Error GoTo 0

    If Not CBool(lMatch) Then
      wsImport.Cells(lRow, 1).EntireRow.Delete
    End If
  Next
End Sub

但是,这需要大量时间。在 150 行上执行此操作需要几分钟的处理时间。我的文档可能长达 1000 行。

基本上我想删除指定工作表上的所有行,除了AE4:AE?? 中指定的行号(这是由 numRows 计算的)在不同的工作表上。

数据范围不连续,AE4:AE?? 可以将数字 3、4、5、33、66、101、110 列为要保留的行。所有其他行都将被删除。

有没有更好的方法来实现我的目标?

我听说自动过滤器要快得多,但我不知道如何在此处应用它,因为我不匹配字符串或单元格中的任何内容,仅匹配行号。

编辑: 根据建议,我尝试了自动过滤方式:

Dim rowsToKeep() As Variant: rowsToKeep = ws.Range("AE4:AE" & numRows)
Dim allRows As Range: Set allRows = Range("ZZ1:ZZ" & numRowsInBBS)

With wsImport
.Range(allRows.Address).Formula = "=row()"
.Range(allRows.Address).AutoFilter Field:=1, Criteria1:=rowsToKeep, Operator:=xlFilterValues
.Range(allRows.Address).SpecialCells(xlCellTypeVisible).EntireRow.Delete
.Range(allRows.Address).AutoFilter Field:=1
End With

我正在尝试: 将AE4:AE?? 范围内的数据设置为数组的数据 - 然后使用 ZZ 作为包含行号的辅助列 - 然后过滤掉我想保留的行 - 然后删除所有可见的行 - 然后显示被过滤的行

但是,过滤器隐藏了所有内容,这表明 rowsToKeep 有问题,是的,另一张表上的 AE4:AE?? 确实包含值。

【问题讨论】:

  • 到目前为止,您对 AutoFilter 方法进行了哪些尝试(是的,它更快)?提示:您当然可以添加一个帮助列并用“=row()”填充它,然后在那里应用自动过滤器......
  • 你有没有试过把整个数据集读入一个数组,然后从数组中删除你不需要的,然后输出数组?
  • @RikSportel 我添加了一个尝试使用 AutoFilter 方式的编辑,但它不太有效。

标签: excel vba


【解决方案1】:

试试这个(未经测试

在循环中删除行总是会比较慢。下面的代码所做的是将需要删除的行存储在一个范围对象中,然后在循环结束时一次性删除它们。

Dim delRng As Range

For lRow = 1 To numRowsInBBS
    On Error Resume Next
    lMatch = Application.Match(lRow, ws.Range("AE4:AE" & numRows).Value, 0&)
    On Error GoTo 0

    If Not CBool(lMatch) Then
        If delRng Is Nothing Then
            Set delRng = wsImport.Rows(lRow)
        Else
            Set delRng = Union(delRng, wsImport.Rows(lRow))
        End If
    End If
Next

If Not delRng Is Nothing Then delRng.Delete

使用CountIf未经测试

Dim delRng As Range

For lrow = 1 To numRowsInBBS
    If Application.WorksheetFunction.CountIf(ws.Range("AE4:AE" & numRows), lrow) > 0 Then
        If delRng Is Nothing Then
            Set delRng = wsImport.Rows(lrow)
        Else
            Set delRng = Union(delRng, wsImport.Rows(lrow))
        End If
    End If
Next

If Not delRng Is Nothing Then delRng.Delete

【讨论】:

  • Invalid Procedure call or argument在线Set delRng = Union(delRng, wsImport.Rows(lRow))
  • 抱歉有错字。解决它。请立即尝试
  • 它似乎只删除了行的第一个“区域”,这是我可以描述它的唯一方法。就像在我原来的帖子中一样,3,4,5 将被删除,但 33,66, 101,110 仍然存在
  • 你测试了这两种方法?
  • 忽略这个,还在半睡半醒。我想说的是,它似乎摆脱了第一个“要保留的数字”的行,然后保留了之后的所有内容。现在将尝试第二种方法并让您知道。
猜你喜欢
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多