3

私のプロジェクトでは、ギザギザの配列、つまり要素も配列である配列をよく使用します。

知るまで、これらの配列を次のように定義することしかできませんでした:

dim subarray(1 to 3) as Integer
dim MyArray(1 to 5) as Variant
subarray(1) = 40
subarray(2) = 50
subarray(3) = 60

MyArray(1) = subarray

しかし、私はこのようなことをしたいと思います:

dim MyArray(1 to 5)(1 to 3) as Variant/Integer
MyArray(1)(1) = 40

上記の例はコンパイルされません。ネストされた配列を直接宣言する同様の有効な方法はありますか?

編集:正しい用語は、「ネストされた配列」ではなく「ジャグ配列」です。

EDIT2: インデックスと値の間の混乱を防ぐために、例の値を編集しました。

4

3 に答える 3

13

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)が含まれているため、実行時にエラーが発生します。IntegersWorksheet

リサイズがめんどくさい

ジャグ配列の利点の 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

配列に再割り当てする必要がある理由はtempIntsouter配列が VBA で値によるセマンティクスを使用するためです。つまり、配列を変数に代入する場合 ( のようにtempInts = outer(2)、配列全体をコピーします。配列が長い場合 (数千要素など) は非常にコストがかかり、配列に文字列が含まれる場合はさらにコストがかかります。単一の文字列もコピーする必要があります。

ギザギザのコレクション

良い:

  • 要素を追加および削除するための単純な構文
  • ギザギザ配列と同じくらい柔軟
  • コレクションは参照によるセマンティクスを使用するため、割り当ては安価であり、同じコレクション オブジェクトへの複数の参照を持つことができます。

悪い:

  • ジャグ配列と同様に、型安全性はありません

内部配列に要素を頻繁に追加する場合はCollection、配列の代わりにオブジェクトを使用する方がはるかに簡単です。Collections は要素のデータ型を強制しないため、これには配列を使用する場合と同じ欠点が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
于 2013-10-29T14:03:15.590 に答える
1

配列の配列:

Dim aa(), ax(),  dd,  x(), xx(), x2()  ' all are " As Variant"

' Array of Arrays - Variant(0 To 2) with 3 Variant(0 To 2) ( 3 Variant/Integer each )
aa = Array( Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9) )
aa(0)(0) = 0

' Array of "Excel" arrays - Variant(0 To 2) with 3 Variant(1 To 3) (3 Variant/Integer each)
ax = Array([{1,2,3}], [{4,5,6}], [{7,8,9}])
ax(0)(1) = 0

別のオプションは、コレクションのコレクション、または辞書の辞書です。

Set dd = CreateObject("Scripting.Dictionary")
Set dd(2) = CreateObject("Scripting.Dictionary")
dd(2)(4) = 24


いくつかの「Excel」長方形配列の例 (VBA 型ではなく、Excel 式でも機能するため):

' "row" array starts at 1 - Variant(1 To 3) with 3 Variant/Integer each
x = [{1,2,3}]
x(1) = 0

' "column" array starts at 1, 1 - Variant(1 To 3, 1 To 1)
xx = [{1;2;3}]
xx(1, 1) = 0

' "Excel" rectangular array - Variant(1 To 3, 1 To 3)
x2 = [{1,2,3;4,5,6;7,8,9}]
x2(1, 1) = 0

Stop ' pause to check the types in the Locals window
于 2016-07-25T13:01:29.613 に答える
0

Joshua が言うように、ジャグ配列を直接宣言するための特定の VBA 構文はありません。
ただし、ジャグ配列は通常の VBA 規則に従って割り当てられます。

Dim a as integer
dim v as variant
a=17
v=a
a=19

V が 19 になるとは思わないでください。

于 2013-10-28T23:17:25.433 に答える