如何在Excel VBA中更好地管理内存以防止宏减速?

时间:2015-03-24 13:36:32

标签: excel performance vba excel-vba

背景

我继承了相当多的Excel VBA代码,这些代码很不稳定且运行缓慢。该代码将用户输入模拟成数千次,然后生成输出文件以发送给其他一些用户。到目前为止,我通过消除复制/粘贴,通过在数组内工作而不是直接访问工作表和单元格,删除不必要的代码,以及将许多易失性公式重新处理成更好的东西,在性能方面取得了很大的进步。

在我进行更改之前,运行此报告以模拟用户输入每个用户大约需要65秒(并且大约有4,300个用户)。那是279,500秒(大约77.6小时)。这是假设一个恒定的速度,宏开始的速度相同。事实并非如此。实际上,当它一夜之间处理时,宏会显着减慢,达到每个用户超过120秒的程度。

问题

在我的代码清理和性能改进之后,我得到了宏,每个用户大约10秒开始,这是一个很好的速度。我让这个宏在昨晚一夜之间运行,今天早上来看看它现在每个用户大约需要花费90秒,所以我在一夜之间遇到了很大的性能下降。

我的问题是:如果宏随着时间的推移而如何防止这种减速发生?

研究

我并非没有想法。目前,我的想法是,我需要关闭并重新打开Excel工作簿,因为它们陷入垃圾陷入困境。我的一个想法是使用本机VB.NET应用程序打开Excel工作簿并运行宏。每500个左右的用户,我可以在工作簿的单元格中的某处写入相关变量,保存并关闭工作簿,然后重新打开它以从我离开的地方继续。这对我来说似乎并不优雅。此外,可能很难说服其他人我需要引入一个新的"技术(VB.NET)。人们对此很奇怪,并且更喜欢原生的VBA解决方案。

有没有更好的方法来管理Excel,这样我就不必创建新的VB.NET应用程序并进行保存/关闭/打开?

我想补充说,没有特定的违规代码,随着时间的推移,它只会减慢(仍然有效!)。

1 个答案:

答案 0 :(得分:8)

一些可以提供帮助的基本内容,我相信您已经尝试过最多:

  • 设置Application.Calculation = xlCalculationManual
  • 设置Application.ScreenUpdating = False
  • 设置Application.EnableEvents = False

关于上述内容的说明,始终假设您的代码将失败并确保使用适当的错误处理程序将这些设置重置为默认值


  • 立即使用DoEvents将控制权交还给处理器,可能会建立一些需要完成的流程以释放资源。
  • 尽可能使用直接布尔比较。

而不是:

If someVar > 5 Then
    boolVar = True
Else
    boolVar = False
End If

考虑使用

boolVar = someVariable > 5
  • 如果必须使用If / Else语法,请查看Select Case语句是否更合适。
  • 使用用户定义的函数(UDF)而不是重复代码
  • 在可能的情况下始终避免循环,使用范围时几乎总有另一种方式(例如,考虑自动过滤)。
  • 使用工作表函数(例如WorksheetFunction.SumIf()) - 不要重新发明轮子!
  • 查找.Select之类的任何实例并删除,您可以直接访问对象的属性和方法而无需选择它。
  • 尽可能使用Application.Goto代替.Activate
  • 在不再需要时从内存中释放对象,例如
    Set myObjectVar = Nothing
  • 使用vbNullString代替""
相关问题