为什么在有collections的情况下在VBA中使用数组?

许多人在Excel / VBA中广泛使用数组来存储数据列表。 但是,在我看来,有更多的收集对象更方便(主要是:不需要重新定义列表的长度)。

所以,我真诚地问自己,如果我错过了什么? 为什么其他人仍然使用数组来存储数据列表? 这仅仅是过去的宿醉吗?

使用数组而不是集合(或字典)的几个原因:

  • 你可以使用Range("A1:B12") = MyArray轻松地将数组传递给范围(反之亦然)
  • 集合只能存储唯一的键,而数组可以存储任何值
  • 集合必须存储一对(键,值),而你可以存储任何数组

请参阅Chip Pearson关于arrays的文章以获得更好的理解

更好的问题是为什么人们会使用字典集合(好吧,集合是标准的VBA,而你必须导入字典)

@CharlesWilliams答案是正确的:循环遍历数组的所有值比迭代一个集合或字典更快:当我需要的时候,总是使用字典的Keys()或Items()方法 – 两个方法都返回一个向量数组。

注意:我使用的Dictionary类远远超过了我使用的集合,Exists()方法太有用了。

collections和字典存在或当然存在缺陷。 其中之一就是数组可以是2维甚至3维 – 对于列表数据而言,这是一个更好的数据结构。 你可以将数组存储为一个集合的成员,但是有一些缺点:其中一个是你可能没有获得对该项目的引用 – 除非你使用arrItem = MyDictionary(strKey)你几乎肯定会得到一个'ByVal数组的副本; 如果您的数据是dynamic的,那么这很糟糕,并且可能会受到多个进程的影响。 这也很慢:大量的分配和释放。

最糟糕的是,如果我有一个数组(或对象!)作为成员的集合或字典,我不太相信VBA会释放内存:不是超出范围,不是通过Set objCollection = Nothing ,甚至不是objDictionary.RemoveAll – 很难certificate问题存在于VBE中有限的testing工具箱中,但是在字典中使用数组的应用程序中,我已经看到了足够的内存泄漏,以至于需要谨慎。 这就是说,我从来没有使用一个数组没有擦除命令的地方。

@JMax解释了数组的另外一个优点:你可以在工作表的单个'hit'中填充一个数组,然后用一个'hit'把你的工作写回去。

当然,通过构造索引数组(Indexed Array),您可以获得两全其美的效果:一个二维数组,其中包含关联的集合或字典对象,其中存储某种行标识符作为关键字,行序列作为数据项。

自动resize的集合较慢(理论上讲,不同的实现显然会有自己的里程)。 如果你知道你有一个设定数量的条目,你只需要以线性的方式访问它们,那么传统的数组是正确的方法。