【问题标题】:CurrentRegion.SpecialCells(xlCellTypeVisible) too slow - Tips to Improve performance?CurrentRegion.SpecialCells(xlCellTypeVisible) 太慢 - 提高性能的技巧?
【发布时间】:2014-06-17 05:03:37
【问题描述】:

我正在尝试自动化具有 5 个不同信息源的报告。我试图使用 ListObjects 将不同表的 UNION 合并为一个,除了复制第一个 ListObject 的第一列时,一切正常。复制第一列大约需要 2 分钟,接下来的列不到 1 秒。

每次运行 VBA 脚本时,我都会删除目标表的所有行,以使用 0 行的 ListObject 启动 VBA 脚本。

我将尝试解释它是如何工作的:

Sub ProcesarPresupuesto() 
'This is the first macro that process and copy the information of the first source

 Application.ScreenUpdating = False
 Application.DisplayAlerts = False
 Application.Calculation = xlCalculationManual

'<Here> I add several columns and process the information of this first source, I keep all the rows as values using the Function: AddColumnFormula (at the end of this example). I think this is not causing the problem.

'Then I fill all the Blanks Cells to avoid having empty cells in my final table.
Sheets("Origin").Select
Selection.CurrentRegion.Select
On Error Resume Next
Selection.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "Null"
On Error GoTo 0

'When I have the ListObject ready I start copying the columns to the destination

Sheets("Destination").Select
Range("A1").Select
While ActiveCell.Value <> ""
Call CopyColumn("Origin", ActiveCell.Value, "Destination")
ActiveCell.Offset(0, 1).Select
Wend

End Sub

我认为这应该非常快。如果我只删除目标 ListObject 的值并将行保持为空,则会立即复制第一列,因此我认为问题与 Excel 如何计算要添加到 ListObject 的第一行有关。当表为空时,是否有更好的方法来复制列?我真的做错了什么吗?

这是函数 CopyColumn

Function CopyColumn(Origin, ColumnName, Destination)
    Range(Origin & "[[" & ColumnName & "]]").Copy Destination:=Range(Destination & "[[" & ColumnName & "]]")
End Function

这是我用来处理列的函数

Function AddColumnFormula(DestinationSheet, TableName, ColumnName, Value)

Set NewColumn = Sheets(DestinationSheet).ListObjects(TableName).ListColumns.Add
NewColumn.Name = ColumnName

Set Rango = Range(TableName & "[[" & ColumnName & "]]")
Rango.Value = Value
Rango.Copy
Rango.PasteSpecial (xlPasteValues)

End Function

提前感谢您的时间和回答

【问题讨论】:

  • 这个范围的地址是什么? Range(Origin &amp; "[[" &amp; ColumnName &amp; "]]")?添加MsgBox Range(Origin &amp; "[[" &amp; ColumnName &amp; "]]").Address,我们看看它显示了什么。
  • 感谢@DavidZemens 的帮助,它为我提供了 Range($A$2:$A$42174) 源代码中第一列的范围。好像没问题。
  • 嗯。我在 45,000 行数据上运行您的代码,复制 7 列(screenupdating = False)不到一秒,screenupdating = True 不到 2 秒...
  • 嗨@DavidZemens 我在周末尝试过这个工作,但我并不走运。这是我的文件的一个示例。我删除了一些不用于此宏的工作表。这里奇怪的是,当我在另一台计算机上测试它时,它工作得更好,但它仍然很慢。宏被调用:ProcesarPresupuesto,它位于模块“GenerarReporte”link
  • 我跑了一次,速度有点慢,但我没有计时。然后我对ProcessarPresupuesto做了一些改动,花了1m16s。我又尝试了一些不同的成功,最近花了 3 分钟 13 秒,但大多数处决每次大约 2 分钟。在那次尝试中,我放入了一些 Debug.Print 语句,我认为问题出在 ...CurrentRegion.SpecialCells(xlCellTypeBlanks) 上——该语句需要 2 分 53 秒来评估。我会再看一会儿,但我认为这是罪魁祸首:CurrentRegionSpecialCells 都是昂贵的操作。可能有更好的方法来做到这一点。

标签: excel vba performance listobject


【解决方案1】:

我对您提供的文件进行了一些测试。它很慢,但我一开始没有计时。我看到了一些修改代码的机会,可能会提高性能,计时器花了 1 分 16 秒。

我尝试了更多的东西,但都取得了不同程度的成功,使用 Debug.Print 语句来通知我代码的哪一部分正在运行以及它们花费了多长时间。大多数处决每次大约 2 分钟,最慢的是 3 分 13 秒。

在最后 3 分 13 秒的尝试中,我将注意力集中在:

...CurrentRegion.SpecialCells(xlCellTypeBlanks)

这是值得怀疑的,因为 CurrentRegionSpecialCells 方法都可能很昂贵。将它们结合起来似乎是灾难的根源。

我想我会尝试一个简单的迭代,只是为了比较性能,令我惊讶的是,我能够对 42,000 行和 32 列数据执行一个简单的 For each 循环,这将在大约 14秒,总运行时间约为 30 秒。

这是我用于循环的代码:

Dim cl As Range
'Debug.Print "For each ..." & Format(Now(), "hh:mm:ss")
For Each cl In wsP.ListObjects(1).DataBodyRange
    If cl.Value = vbNullString Then cl.Value = "Null"
Next
'Debug.Print "End loop " & Format(Now(), "hh:mm:ss")

这是我最近的三个结果:

31 seconds:    
    Commencar a 21:09:25
    For each ...21:09:38
    End loop 21:09:52
    CopiarColumnaListOBjectaVacia...21:09:52
    Finito : 5/5/2014 9:09:56 PM

30 seconds:    
    Commencar a 21:10:23
    For each ...21:10:36
    End loop 21:10:49
    CopiarColumnaListOBjectaVacia...21:10:49
    Finito : 5/5/2014 9:10:53 PM

34 seconds:    
    Commencar a 21:18:42
    For each ...21:18:55
    End loop 21:19:09
    CopiarColumna... 21:19:09
    Finito : 5/5/2014 9:19:16 PM

我已将 XLSB 的修订版保存在 Google Docs 上,以便您可以完整查看。

https://drive.google.com/file/d/0B1v0s8ldwHRYZWhuTmRuaDJoMzQ/edit?usp=sharing

正如我所说,我确实对这个子例程和RenombraColumna 做了一些更改,但事后看来,虽然这些可能会提高效率,但我认为问题的根源在于CurrentRegion.SpecialCells

我希望您不介意我修改了这个问题的标题以更适合特定问题。正如最初所说,这个问题不太可能帮助其他有相同症状的人。

【讨论】:

    猜你喜欢
    • 2021-06-06
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    相关资源
    最近更新 更多