-1

我目前正在开发一个与 Microsoft Excel 交互的报告套件。我主要使用的语言是 Java、Perl 和 Python。我会认为自己是一个新手程序员。我选择使用 VBA 的唯一原因是因为它被建议为在编写 Microsoft Office 扩展程序时使用的最佳语言。

考虑到这些,我绝对讨厌数组在 VBA 中的执行方式。具体来说,必须定义数组的大小,而不是让它动态增长。

如何创建动态数组而无需重新调整它们?我试图避免这种情况,因为它显然是资源密集型的。

我找到的唯一解决方案是如果您使用单个循环,您可以将元素的数量设置为等于循环的上限(假设计数 1 次迭代)。

当我不使用单个循环并且这不是一个选项时,我该怎么办?

重新调整是不可避免的吗?

4

2 回答 2

4

这不是一个“数组”,但 VBA 确实有一个Dictionary对象(此链接也很有用)可能适合您的需要。您需要添加对 的引用Microsoft Scripting Runtime,然后您可以创建一个无类型键控字典(实际上Item属性是 a Variant),它可以动态增长。链接有更完整的示例,但用法基本上是:

Set dict = New Dictionary

'Example for adding item to Dictionary
For i = 1 to 100
    dict.Add Key:=i, Item:=someData
Next

'Example for retrieving item from dictionary by Key
For i = 1 to 100
    Debug.Print dict(i)
Next

还有一个Collection对象,它提供类似的功能和类似的用法,但不需要添加对 的引用Microsoft Scripting Runtime,但Dictionary提供了一些更有用的方法,例如dict.Exists()检查特定键是否存在。还有一些属性可以让您将所有项目.Keys或键提取为-typed 数组.ItemsDictionaryVariant

即使您明确声明不想重新调整数组,在创建后调整数组大小的唯一替代方法是Preserve在 redim 语句上使用修饰符。这将允许您在创建后灵活地更改数组大小。我说“一些灵活性”的原因是您只能更改数组的最后一个维度。

Dim myarray(2, 2)
Redim Preserve myarray(2, 4) 'this works
Redim Preserve myarray(3, 4) 'this is not allowed

正如您所提到的,这是资源密集型的,因为您实际上并没有更改数组的大小,您实际上只是创建了一个新数组并将旧数组的内容复制到其中。

最后一个选择是从 VBA 切换到 .NET。假设您有适当版本的 Visual Studio可供您使用,您将可以访问VSTO而不是 Office 附带的 VBA 编辑器,然后您将能够为 Excel 和其他 Office 开发符合 CLR 的加载项产品。然后,您将有权访问所有 .NET 集合。同样,这些不是“数组”,因为 .NET 数组具有相同的限制(它们无法调整大小),但您拥有可能适合您需要的动态大小的集合。

于 2012-11-28T14:03:57.090 回答
1

这是一个相当古老的问题,但我想为已经给出的答案添加一些上下文。

VBA 不直接为动态数组提供类型,并且需要重新调整以更改大小。这似乎效率低下,因为它可能需要将数组的内容复制到内存中的新位置。然而,这正是动态数组在幕后所做的事情:当它们满了时,它们通常会加倍大小,而当它们下降到四分之一以下时,它们会缩小到一半。这保证了添加和删除 O(1) 项的平均运行时间。

因此,如果由于索引查找速度快而想要在 VBA 中使用数组并且还需要动态大小,则可以简单地模拟这种行为。

编辑:一个小的修正。在数组末尾添加或删除时,您会获得 O(1) 的平均性能。对于数组,在随机位置添加总是 O(N)。(你必须把所有东西都移位。)如果你想在随机位置添加,你最好使用链表,它的索引查找性能很差(但是枚举有很好的性能),一个跳过列表,它更复杂但有良好的查找性能牺牲了插入性能或散列集,其键查找非常快但需要更大的空间。

于 2017-06-04T18:40:26.933 回答