VBA でコレクションのコレクションを作成するには、さまざまな方法があります。それらにはすべて利点と欠点があります。
多次元配列
良い:
- 単純な構文 (変数は 1 つだけ)
- タイプセーフティ。の行列のすべての要素
Integer
は既知であり、s であることが強制されますInteger
。
- 非常に高速な配列アクセス
悪い:
- 内部配列のサイズに大きな違いがある場合、行列には未使用の「セル」があるため、行列はいくらかのスペースを浪費します。
- で変更できるのは、最後の次元の境界のみです
ReDim Preserve
。したがって、すべてのデータを消去せずに行列に「列」を追加することはできません。
コンマで区切られた複数の境界を含めることにより、多次元配列を宣言します。
Dim intMatrix(0 to 2, 0 to 4) As Integer
最初に境界なしで配列を宣言すると、多次元配列の最後の次元を動的に増やすことができます。
Dim intMatrix() As Integer ' Uninitialized dynamic array
ReDim intMatrix(0 to 4, 0 to 2) ' Initialize as a matrix
ReDim Preserve intMatrix(0 to 4, 0 to 3) ' Add another "row" to the matrix, preserving existing data
ジャグ配列
良い:
悪い:
- コンパイル時の型の安全性を失う
- ネストされた構造のため、少しトリッキー/面倒です
- 内側の配列のサイズを変更するのは厄介で費用がかかります
type の外側の配列を宣言し、外側の配列Variant()
の要素に他の配列を割り当てることで、ジャグ配列を作成できます。
Dim outer() As Variant ' Dynamic, so new inner arrays can be added
Dim inner() As Integer ' Dynamic, so new elements can be added
ReDim outer(0 to 3)
ReDim inner(0 to 4)
outer(2) = inner
コンパイル時の型情報が失われました
コンパイラが外側の配列について「知っている」のは、それが何かを含むことができるということだけです。したがって、次のコードがコンパイルされます。
Set objWorksheet = outer(2)(3)
ただし、内部配列 atには オブジェクトではなくouter(2)
が含まれているため、実行時にエラーが発生します。Integers
Worksheet
リサイズがめんどくさい
ジャグ配列の利点の 1 つは、内側の配列をさまざまなサイズにできることです。ただし、内部配列のサイズを直接変更することはできません。VBA は構文を処理できません。以下はコンパイルされません。
ReDim Preserve outer(2)(0 to 5)
内部配列のサイズを変更するには、最初に内部配列を別の変数に割り当て、その変数のサイズを変更してから、それをジャグ配列に割り当て直す必要があります。
Dim tempInts() As Integer
tempInts = outer(2)
ReDim Preserve tempInts(0 to 5)
outer(2) = tempInts
配列に再割り当てする必要がある理由はtempInts
、outer
配列が VBA で値によるセマンティクスを使用するためです。つまり、配列を変数に代入する場合 ( のようにtempInts = outer(2)
、配列全体をコピーします。配列が長い場合 (数千要素など) は非常にコストがかかり、配列に文字列が含まれる場合はさらにコストがかかります。単一の文字列もコピーする必要があります。
ギザギザのコレクション
良い:
- 要素を追加および削除するための単純な構文
- ギザギザ配列と同じくらい柔軟
- コレクションは参照によるセマンティクスを使用するため、割り当ては安価であり、同じコレクション オブジェクトへの複数の参照を持つことができます。
悪い:
内部配列に要素を頻繁に追加する場合はCollection
、配列の代わりにオブジェクトを使用する方がはるかに簡単です。Collection
s は要素のデータ型を強制しないため、これには配列を使用する場合と同じ欠点がVariant
ありますが、とにかくギザギザの配列を使用するにはそれを行う必要があります。
Dim cAnimals As New Collection
' Let's add stats on the Cheetah
Dim cCheetah As New Collection
' Easy to add inner collections to the outer collection. Also, cCheetah refers
' to the same collection object as cAnimals(1).
cAnimals.Add cCheetah
' Easy to add items to inner collection.
' Working directly with the cCheetah collection:
For Each vMeasurment In GetMeasurements("Cheetah")
cCheetah.Add vMeasurement
Next
' Working on the same collection by indexing into the outer object
For i = 1 To cAnimals.Count
For j = 1 To cAnimals(i).Count
cAnimals(i)(j) = cAnimals(i)(j) * dblNormalizingFactor
Next
Next