26

我在一个大型电子表格上运行 VBA 代码。如何清除过程/调用之间的内存以防止发生“内存不足”问题?

谢谢

4

7 回答 7

16

我找到了解决方法。起初它似乎会花费更多时间,但实际上由于更少的交换和更多的可用内存,它使一切工作更顺畅、更快。这不是一种科学的方法,它需要一些测试才能起作用。

在代码中,让 Excel 时不时地保存工作簿。我不得不遍历一张有 360 000 行的纸,它严重窒息。每 10 000 次后,我让代码保存工作簿,现在即使在 32 位 Excel 上它也能像魅力一样工作。

如果您同时启动任务管理器,您可以看到每次保存后内存利用率急剧下降。

于 2015-11-20T14:11:44.580 回答
15

帮助释放内存的最佳方法是使大对象无效:

Sub Whatever()
    Dim someLargeObject as SomeObject

    'expensive computation

    Set someLargeObject = Nothing
End Sub

另请注意,全局变量仍然从一个调用分配到另一个调用,因此如果您不需要持久性,则不应使用全局变量或在不再需要它们时将它们无效。

但是,如果出现以下情况,这将无济于事:

  • 你需要在程序之后的对象(显然)
  • 您的对象不适合内存

另一种可能性是切换到 64 位版本的 Excel,它应该能够在崩溃之前使用更多 RAM(32 位版本通常限制在 1.3GB 左右)。

于 2013-01-18T10:36:34.810 回答
3

答案是你不能明确地但你应该在你的例程中释放内存。

一些提示虽然可以帮助记忆

  • 确保在退出例程之前将 object 设置为 null。
  • 如果需要,请确保在对象上调用 Close。
  • 除非绝对必要,否则不要使用全局变量

我建议在一次又一次地执行例程后检查内存使用情况,您可能会遇到内存泄漏。

于 2013-01-18T10:39:24.827 回答
1

如果您对大型数据集进行操作,则很可能会使用数组。对我来说,从 500 000 行和 30 列工作表创建几个数组导致了这个错误。在创建另一个之前,我通过使用下面的行来摆脱对我来说不再需要的数组来解决它:

Erase vArray

此外,如果仅使用 30 列中的 2 列,则创建两个 1 列数组而不是一个具有 30 列的数组是一个好主意。它不影响速度,但内存使用量会有所不同。

于 2017-09-16T01:11:34.873 回答
1

发现这个线程正在寻找解决我的问题的方法。我的需要一个不同的解决方案,我发现它可能对其他人有用。我的宏正在删除行、向上移动并将行复制到另一个工作表。在仅处理了大约 4000 条记录后,内存使用量激增至数次,并导致“内存不足”。什么为我解决了?

应用程序.screenupdating = false

在我的代码开头添加了这一点(一定要在最后再次使它成为真的)我知道这会使它运行得更快,它确实做到了..但不知道内存的事情。

进行这个小改动后,内存使用量没有超过 135 mb。为什么这行得通?真的不知道。但它值得一试,可能适用于你。

于 2019-03-08T06:53:57.943 回答
0

我可以通过简单地初始化一个稍后在我的程序中使用的变量来修复这个错误。当时,我没有在我的类/模块中使用 Option Explicit。

于 2020-02-18T20:16:24.300 回答
0

我有一个类似的问题,我自己解决了......我认为部分原因是我的代码占用了太多的内存,而太多的“大事”

在我的应用程序中 - 工作簿出来并获取另一个部门的“每日报告”......我提取了我们团队需要的所有信息(以尽量减少错误和数据输入)。

我直接拉入他们的床单......但我讨厌他们使用合并单元格的事实......我摆脱了(即取消合并,然后找到生成的空白单元格,并填充上面的值)

我让我的问题消失了

a)仅取消合并“使用的单元格” - 而不是仅仅尝试执行整个列......即找到列中最后使用的行,并仅取消合并这个范围(我抓住的每张纸上都有 1000 行)

b)知道撤消只关注最后的〜16个事件......在每个“取消合并”之间 - 我放置了15个事件来清除“撤消”中存储的内容,以最大限度地减少占用的内存量(即转到一些包含数据的单元格..并复制//粘贴特殊值...我猜测 30 张每张有 3 列数据的累积总和可能会对作为撤消的一侧的内存集征税

是的,它不允许任何撤消的机会......但整个目的是清除旧信息并提取新的时间敏感数据进行分析,所以这不是问题

听起来老土 - 但我的问题消失了

于 2015-09-24T17:46:41.117 回答