【问题标题】:Excel 2007 VBA Array Size LimitExcel 2007 VBA 数组大小限制
【发布时间】:2011-10-19 06:35:49
【问题描述】:

我发现的许多资料表明,VBA 代码的数组大小取决于机器中的内存量。然而,这对我来说并非如此。我正在运行以下非常简单的代码来测试:

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

但是,如果我将大小更改为 600x600x600,则会出现内存不足错误。我使用的机器有 16Gb 的 RAM,所以我怀疑物理 RAM 是问题。

我使用的是 Excel 2007。是否有让 VBA 使用更多 RAM 的技巧?

【问题讨论】:

    标签: arrays vba excel memory


    【解决方案1】:

    如果有一个我们可以调用的Application.UseMoreMemory() 函数就好了:-)

    唉,我一个都不知道。

    我看到的所有文档都说它受内存限制,但问题不是物理内存,而是您可以使用的虚拟地址空间。

    您应该记住,虽然从 500 增加到 600 看起来只是适度的增加(尽管 20% 本身就足够大了),因为您是在三个维度上这样做的,所以结果是存储需求接近两倍。

    根据内存,Excel 2007 使用短整数(16 位)作为布尔类型,因此,您的 5003 数组至少会占用大约 250M (500x500x500x2)。

    将所有尺寸增加到 600 会得到 600x600x600x2,或大约 432M。

    在 32 位机器中可能拥有的 2G 可用地址空间内一切正常(我不知道 Excel 2007 64 位版本),但这些东西是 不小,而且你还必须与其他东西共享该地址空间。

    看看你从什么时候开始开始得到错误会很有趣。

    作为第一步,我将研究对如此大的阵列的需求。它可以通过不同的方式实现,例如对数组进行分区,以便在任何时候只有一部分在内存中(类似于手动虚拟内存)。

    对于真正的随机访问来说,这不太可能表现得那么好,但对于更多的顺序访问来说应该不会太糟糕,并且至少会让你继续前进(一个缓慢的解决方案比一个不工作的解决方案更可取)。

    另一种可能性是抽象出位处理,以便您的布尔值实际上存储为位而不是单词。

    您必须为getBoolsetBool 提供函数,在单词数组上使用位掩码运算符,同样,性能不会那么崩溃,但您至少可以做到达到相当于:

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

    与往常一样,这取决于您需要数组的用途及其使用模式。

    【讨论】:

    • 从 500 增加到 600 只是我做的一个粗略的工作。不幸的是,基本上我们正在尝试将 excel 用于它确实不是为它设计的东西,但截止日期是下周,所以我们现在不能真正改变!感谢您的想法,我会继续关注事情的进展。
    • 您继续插电之前,您可能希望确保将这种潜在延迟通知管理层。他们真的不喜欢惊喜:-)
    • 快速说明您使用位而不是布尔值的想法,我仅将布尔值用于我的测试,在我们的实际工作中,我们使用的结构体包含大量有关该过程的数据,所以我们得到的比用布尔值得到的要少得多。可悲的是,我已经尽可能地减少了这些=(
    • 更准确地说是536.870911875 MB 或2^32-1 Bytes。 Tbh 真的很遗憾 Excel 存储了一个指向数组每个字节的指针......这也没什么意义,它应该是一个指向每个单元格的指针......
    【解决方案2】:

    运行一些测试后,看起来 32 位 VBA 的限制约为 500MB,64 位 VBA (Excel 2010-64) 的限制约为 4GB。
    我不知道这些 VBA 限制是否会减少如果您在同一个 Excel 实例中使用大量工作簿/数据透视内存。

    【讨论】:

    • 这似乎与我得到的有关,谢谢。可以试试看能不能搞到64位的——用买了但很少用的64位机吧!
    【解决方案3】:

    正如@paxdiablo 提到的,数组的大小约为 400+ Mb,对于 32 位 Excel,理论上最大为 2 Gb。 VBA 宏很可能在内存使用方面受到限制。此外,数组的内存块必须是连续的内存块,这使得分配更加困难。因此,您可以分配十个 40 Mb 大小的数组,但不能分配一个 400 Mb 大小的数组。检查一下。

    【讨论】:

    • 不应该分配器移动内存块来创建一个连续的空间吗?这需要时间,但我认为它不会抛出内存不足错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2023-04-02
    • 2013-06-30
    • 2012-05-13
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多