简体   繁体   English

Excel 2007 VBA数组大小限制

[英]Excel 2007 VBA Array Size Limit

Numerous sources I have found have suggested that the size of arrays for VBA code depends upon the amount of memory in the machine. 我发现的众多资源表明,VBA代码的数组大小取决于机器中的内存量。 This however hasn't been the case for me. 然而,对我来说并非如此。 I'm running the following, very simple, code to test: 我正在运行以下非常简单的代码来测试:

Sub test6()
Dim arr(500, 500, 500) As Boolean
End Sub

However, if I change the size to be 600x600x600, I get an out of memory error. 但是,如果我将大小更改为600x600x600,则会出现内存不足错误。 The machine I'm using has 16Gb of RAM, so I doubt that physical RAM is the issue. 我正在使用的机器有16Gb的RAM,所以我怀疑物理RAM是个问题。

I'm using Excel 2007. Is there a trick to getting VBA to use more RAM? 我正在使用Excel 2007.是否有一个让VBA使用更多RAM的技巧?

It would be nice if there was an Application.UseMoreMemory() function that we could just call :-) 如果有一个我们可以调用的Application.UseMoreMemory()函数会很好:-)

Alas, I know of none. 唉,我什么都不知道。

All the docs I've seen say that it's limited by memory, but it's not physical memory that's the issue, it's the virtual address space you have available to you. 我见过的所有文档都说它受到内存的限制,但问题不在于物理内存,而是你可以使用的虚拟地址空间。

You should keep in mind that, while the increase from 500 to 600 only looks like a moderate increase (though 20% is large enough on its own), because you're doing that in three dimensions, it works out to be close to double the storage requirements. 你应该记住,虽然从500增加到600看起来只是温和的增长(虽然20%自己足够大),因为你在三维中这样做,它可以接近双倍存储要求。

From memory, Excel 2007 used short integers (16 bits) for boolean type so, at a minimum, your 500 3 array will take up about 250M (500x500x500x2). 从内存中,Excel 2007使用短整数(16位)作为布尔类型,因此,至少500 3阵列将占用大约250M(500x500x500x2)。

Increasing all dimensions to 600 would give you 600x600x600x2, or about 432M. 将所有尺寸增加到600将为您提供600x600x600x2,或约432M。

All well within the 2G usable address space that you probably have in a 32-bit machine (I don't know that Excel 2007 had a 64-bit version), but these things are not small, and you have to share that address space with other things as well. 所有这些都在32位机器中可能存在的2G可用地址空间内(我不知道Excel 2007 64位版本),但这些东西都不小,你必须共享那个地址空间与其他事情一样。

It'd be interesting to see at what point you started getting the errors. 看看你在什么时候开始得到错误会很有趣。

As a first step, I'd be looking into the need for such a large array. 作为第一步,我将研究是否需要这么大的阵列。 It may be doable a different way, such as partitioning the array so that only part of it is in memory at any one time (sort of manual virtual memory). 它可以以不同的方式实现,例如对数组进行分区,使得其中只有一部分在任何时间都在内存中(一种手动虚拟内存)。

That's unlikely to perform that well for truly random access but shouldn't be too bad for more sequential access and will at least get you going (a slow solution is preferable to a non-working one). 这对于真正的随机访问来说不太可能表现得那么好,但对于更多的顺序访问来说不应该太糟糕,并且至少会让你前进(慢速解决方案比非工作方式更好)。

Another possibility is to abstract away the bit handling so that your booleans are actually stored as bits rather than words. 另一种可能性是抽象掉位处理,以便你的布尔值实际存储为位而不是单词。

You would have to provide functions for getBool and setBool , using bitmask operators on an array of words and, again, the performance wouldn't be that crash-hot, but you would at least be able to then go up to the equivalent of: 你必须为getBoolsetBool提供函数,在一个单词数组上使用位掩码运算符,再次,性能不会那么崩溃,但你至少可以达到相当于:

' Using bits instead of words gives 16 times as much. '
Dim arr(8000, 8000, 8000) As Boolean

As always, it depends on what you need the array for, and its usage patterns. 与往常一样,它取决于您对阵列的需求及其使用模式。

Having run some tests it looks like there is a limit of about 500MB for 32-bit VBA and about 4GB for 64-bit VBA (Excel 2010-64). 运行一些测试后,32位VBA的限制大约为500MB,64位VBA的限制大约为4GB(Excel 2010-64)。
I don't know if these VBA limits decrease if you are using a lot of workbook/pivot memory within the same Excel instance. 如果您在同一个Excel实例中使用大量工作簿/数据透视内存,我不知道这些VBA限制是否会减少。

As @paxdiablo mentioned the size of array is about 400+ Mb, with theoretical maximum of 2 Gb for 32 bit Excel. 正如@paxdiablo所提到的,数组的大小约为400+ Mb,32位Excel的理论最大值为2 Gb。 Most probably VBA macroses are limited in memory usage. 很可能VBA宏在内存使用方面受到限制。 Also memory block for array must be a contiguous block of memory which makes it allocation even harder. 此外,数组的内存块必须是一个连续的内存块,这使得它的分配更加困难。 So it's possible that you can allocate ten arrays of 40 Mb size, but not one of 400 Mb size. 因此,您可以分配10个40 Mb大小的阵列,但不能分配400 Mb大小的阵列。 Check it. 核实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM