我目前正在开发一个与Microsoft Excel连接的报表包。我使用的语言主要是Java,Perl和Python。我认为自己是一名新手程序员。我选择使用VBA的唯一原因是因为它被建议作为编写Microsoft Office扩展时使用的最佳语言。
考虑到这些事情,我绝对讨厌数组在VBA中执行的方式。具体而言,必须定义数组的大小,而不是允许它动态增长。
如何创建动态数组而不必重新创建它们?我试图避免这种情况,因为它显然是资源密集型的。
我找到的唯一解决方案是如果你使用单个循环,你可以设置元素的数量等于循环的上限(假设计数1次迭代)。
当我不使用单循环时,我该怎么办?这不是一个选项?
重整是不可避免的吗?
答案 0 :(得分:4)
这不是"数组"但是VBA确实有一个Dictionary
对象(这个link也很有用)可能适合您的需求。您需要添加对Microsoft Scripting Runtime
的引用,但是您可以创建一个无类型的键控字典(实际上Item
属性是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
中还有.Items
和Dictionary
个属性,允许您将所有项目或键提取为Variant
类型的数组
即使你明确声明你不想重新调整数组,在创建之后调整数组大小的唯一其他选择是使用redim语句中的Preserve
修饰符。这将允许您在创建后更改阵列大小的灵活性。我说的原因"一些灵活性"你是否只能改变数组的最后一个维度。
Dim myarray(2, 2)
Redim Preserve myarray(2, 4) 'this works
Redim Preserve myarray(3, 4) 'this is not allowed
正如您所提到的,这是资源密集型的,因为您实际上并未更改数组的大小,实际上您只是创建一个新数组并将旧数组的内容复制到其中。
您拥有的最后一个选项是从VBA切换到.NET。假设您有适当的version of Visual Studio,您可以访问VSTO而不是Office附带的VBA编辑器,然后您就可以开发CLR- Excel和其他Office产品的兼容加载项。然后,您可以访问所有.NET集合。同样,这些不是"数组"因为.NET数组具有相同的限制(它们无法调整大小),但是您可以根据需要动态调整大小的集合。
答案 1 :(得分:1)
这是一个相当古老的问题,但我想在已经给出的答案中添加一些背景信息。
VBA不直接为动态数组提供类型,并且需要重新调整才能更改大小。这似乎是低效的,因为它可能需要将数组的内容复制到内存中的新位置。然而,这正是动态阵列在引擎盖下所做的事情:它们通常在装满时加倍尺寸,当尺寸减小到四分之一时缩小到一半尺寸。这保证了添加和删除O(1)项的平均运行时间。
因此,如果您希望在VBA中使用数组,因为索引查找速度很快,并且您还需要动态大小,则可以简单地模拟此行为。
编辑: 一个小小的修正。添加或删除数组末尾的平均性能为O(1)。在随机位置添加对于数组总是O(N)。 (你必须改变一切。) 如果你想在随机位置添加,你应该更好地使用链表,它具有糟糕的索引查找性能(枚举具有良好的性能),跳过列表,这更复杂,但具有良好的查找性能,牺牲了插入性能,或者哈希集,其密钥查找速度非常快但具有更大的空间要求。