我发现的许多来源都暗示VBA代码的数组大小取决于机器中的内存量。然而,对我来说并非如此。我正在运行以下非常简单的代码来测试:
Sub test6()
Dim arr(500, 500, 500) As Boolean
End Sub
但是,如果我将大小更改为600x600x600,则会出现内存不足错误。我使用的机器有16Gb的RAM,所以我怀疑物理RAM是个问题。
我正在使用Excel 2007.有没有让VBA使用更多内存的技巧?
答案 0 :(得分:6)
如果有一个Application.UseMoreMemory()
函数我们可以调用它会很好: - )
我见过的所有文档都说它受内存限制,但问题不在于物理内存,而是你可以使用的虚拟地址空间。
你应该记住,虽然从500增加到600看起来只是适度增加(虽然20%自己足够大),因为你是在三维中做到这一点,它可能是接近两倍的存储要求。
从内存中,Excel 2007使用短整数(16位)作为布尔类型,因此,至少500 3 数组将占用大约250M(500x500x500x2)。
将所有尺寸增加到600将为您提供600x600x600x2,或约432M。
一切都在32位机器中你可能拥有的2G可用地址空间内(我不知道Excel 2007 有 64位版本),但这些东西都是< em> not small,你必须与其他东西分享这个地址空间。
看看你开始获取错误的时间点很有意思。
作为第一步,我将研究是否需要这么大的阵列。它可能是一种不同的方式,例如对数组进行分区,以便任何时候只有部分数据在内存中(某种手动虚拟内存)。
对于真正的随机访问来说,这不太可能表现得那么好,但对于更多顺序访问来说不应该太糟糕,并且至少会让你前进(慢速解决方案比非工作方式更好)。
另一种可能性是抽象掉位处理,以便你的布尔值实际存储为位而不是单词。
你必须为getBool
和setBool
提供函数,在一个单词数组上使用位掩码运算符,同样,性能不会那么崩溃,但你至少会然后能够达到相当于:
' Using bits instead of words gives 16 times as much. '
Dim arr(8000, 8000, 8000) As Boolean
与往常一样,它取决于您对阵列的需求及其使用模式。
答案 1 :(得分:4)
运行一些测试后,32位VBA的限制约为500MB,64位VBA约为4GB(Excel 2010-64)。我不知道这些VBA是否有限制如果在同一个Excel实例中使用大量工作簿/数据透视内存,则会减少。
答案 2 :(得分:0)
正如@paxdiablo所提到的,数组的大小约为400+ Mb,32位Excel的理论最大值为2 Gb。很可能VBA宏在内存使用方面受到限制。此外,数组的内存块必须是一个连续的内存块,这使得它的分配更加困难。因此,您可以分配10个40 Mb大小的阵列,但不能分配400 Mb大小的阵列。检查一下。