VBA – 配列変数の宣言(Dim)、作成、および初期化
In this Article
このチュートリアルでは、VBAで配列変数を宣言(Dim)、作成、および初期化する方法を説明します。
VBAの配列変数とは?
VBAの配列変数は、同じ名前で保存され、同じデータ型を持つ変数のグループと考えることができます。配列は、テキスト、数値、オブジェクトを格納することができます。 配列の要素を参照するには、そのインデックス番号を使用します。 配列変数は、他の変数と同じように Dim、Static、Public、Private キーワードを使って宣言することができます。
静的な配列
配列には、静的な配列と動的な配列の2種類があります。静的な配列は、最初に配列を宣言する際にサイズを指定して宣言します。固定配列とも呼ばれます。
Dim intA(4) as integer
上記の配列は、プロシージャまたはモジュールレベルでDimステートメントを使用して宣言されており、配列のLBound値を宣言していないため、配列のサイズは5です。
タイプミスではありません!配列に4を入力したにもかかわらず、配列のサイズが5になっているのです。これは、配列のインデックスが自動的に0から始まるからです。
配列のインデックス
配列のインデックスは、Option Base 1がコードモジュールの先頭で宣言されていない限り、自動的に 0 から始まります。
Option Base 1が宣言されている場合、配列は自動的に 1 から始まります。 しかし、このような方法で変数を宣言するのは問題があると思います。コードレビューの担当者は、配列がゼロから始まることや、Option Base 1の宣言に気づかないかもしれません。 代わりに、配列の開始位置と終了位置を明示的に宣言するのが望ましいでしょう。
Dim intA(2 to 5) as integer
このようにすると、配列を任意の数(1や0だけでなく)から開始することもできます。
動的な配列
動的な配列とは、実行時にサイズを変更することができる配列のことです。動的な配列は、サイズを指定せずに宣言します。
Dim intA() as integer
配列作成後にReDim文を使って配列のサイズを指定することができます。
ReDim intA(2)
動的な配列のサイズはいつでも変更することができます。ただし、ReDimステートメントを使用した場合、既存の値はすべて消去されてしまいます。既存の値を保持したままサイズを変更するには、ReDim Preserveを使用します。
ReDim Preserve intA(2)
動的な配列はプロシージャ、モジュール、グローバルレベルで宣言できますが、ReDim文はプロシージャ内でのみ使用可能です。
バリアント型配列
バリアント型配列は、より簡単に扱うことができる動的な配列です。
Dim varNames()
データ型(バリアントと仮定)や配列のサイズを指定する必要がないことに注意してください。 後述するように、Array関数を使ってバリアント配列を初期化することができます。(最初に配列のサイズを変更する必要はありません!)
モジュールおよびパブリック配列の宣言
上記のように、配列はプロシージャ内で宣言して、そのプロシージャ内で使用することができます。
Sub StaticArray()
'LBound値を1、UBound値を4とした配列を宣言する
Dim IntA(1 to 4) as Integer
End Sub
しかし、これらはモジュールやグローバルレベルで宣言することもできます。
Option Explicit
'LBound値を1、UBound値を4とした配列を宣言する
Dim IntA(1 to 4) as Integer
Sub StaticArray()
End Sub
この例では、配列変数はこのコードモジュール内の任意の場所で呼び出すことができます。代わりに、VBA プロジェクト全体で使用できるパブリック配列を宣言することができます (次のセクションを参照)。
パブリック配列の宣言
パブリックな静的配列は、パブリック変数と同じように宣言します。
Public strNames(3) as String
この宣言は、モジュールの一番上、Option Explicitの下に書く必要があります。 この宣言は、VBAプロジェクト全体を通して、どのモジュールやプロシージャでも使用することができます。
配列の宣言をモジュールの先頭で行い、Dimキーワードを使用した場合、その配列の使用はそのモジュール内に限定されます。 別のモジュールで配列を使用しようとすると、エラーになります。
配列の初期化
以下の方法で、静的な配列に値を代入することができます。
Sub StaticArray()
'LBound値を1、UBound値を4とした配列を宣言する
Dim IntA(1 to 4) as Integer
'配列を初期化する
IntA(1) = 10
IntA(2) = 20
IntA(3) = 30
IntA(4) = 40
'配列の位置2の結果をイミディエイトウィンドウに表示する
Debug.Print IntA(2)
End Sub
上記のプロシージャを実行すると、イミディエイトウィンドウに20という値が表示されます。
また、同じ方法で動的な配列に値を代入することもできます。
Sub DynamicArray()
'動的配列を宣言するが、添字は省略する
Dim IntA() as Integer
'配列を初期化する
ReDim IntA(1 to 4)
IntA(1) = 10
IntA(2) = 20
IntA(3) = 30
IntA(4) = 40
'配列の位置2の結果をイミディエイトウィンドウに表示する
Debug.Print IntA(2)
End Sub
Array関数
バリアント型配列にのみ使える方法ですが、Array関数を使うことができ、標準の方法を使うよりも簡単かもしれません。
'配列に値を入れる
intA() = Array(10, 20, 30, 40)
ループを使った配列の入力
Excelでセルの範囲をループすることでも、配列に値を入れることができます。
Sub TestDynamicArrayFromExcel()
'配列を宣言する
Dim strNames() As String
'範囲内の行を数えるための整数を宣言する
Dim n As Integer
'ループ用の整数を宣言する
Dim i As Integer
'範囲の行を数える
n = Range("A1", Range("A1").End(xlDown)).Rows.Count
'配列を範囲内の行数にサイズ変更する
ReDim strNames(n)
For i = 0 To n
strNames(i) = Range("A1").Offset(i, 0)
Next i
'配列の値を表示する
MsgBox Join(strNames())
End Sub
配列の再初期化
配列の再初期化は、コードのどの段階でも可能ですが、その場合、配列のその位置に含まれていた元の値が失われます。
Sub StaticArray()
'LBound値を1、UBound値を4とした配列を宣言する
Dim IntA(1 to 4) as Integer
'配列を初期化する
IntA(1) = 10
IntA(2) = 20
IntA(3) = 30
IntA(4) = 40
'配列の位置2の結果をイミディエイトウィンドウに表示する
Debug.Print IntA(2)
'配列の値を再代入する
intA(2)=200
Debug.Print IntA(2)
End Sub
上記の例では、静的な配列は位置2の値を除き、すべての値を保持しますが、この値は200に変更されます。
ReDimの使用
動的な配列を使用する場合、ReDimステートメントで配列のサイズを変更することが出来ます。 ReDimステートメントをコード内で続けて使用することで、必要な回数だけ配列のサイズを変更することができます。 以下のコードでは、intA配列のサイズが2になるように再初期化します。(配列のインデックスはデフォルトでは0から始まります。)
ReDim intA(1) as Integer
つまり、ReDim文を含むコードは、以下の例のようになります。
Sub TestDynamicArray()
'配列を宣言する
Dim intA() As Integer
ReDim intA(2)
'配列に数値を代入します
intA(0) = 2
intA(1) = 5
intA(2) = 9
'1の位置にある数字を表示する
Debug.Print intA(1)
'サイズを変更するために配列を再宣言する
ReDim intA(3)
intA(0) = 6
intA(1) = 8
'今回は1の位置の数字を表示する
Debug.Print intA(1)
End Sub
上記のプロシージャを実行すると、5という値がイミディエイトウィンドウに表示され、ReDimを使って配列のサイズを変更し、再投入すると8という値が表示されるはずです。 しかし、IntA(2)には値を入れておらず、ReDim Preserveも使用していないため、配列のその位置の値は削除され、配列の位置3、4とともにEmpty値となります。
ReDim Preserveの使用
ReDim Preserveを使用すると、配列に含まれる元の値を保持することができます。
Sub TestDynamicArray()
'配列を宣言する
Dim intA() As Integer
ReDim intA(2)
'配列に数値を入力する
intA(0) = 2
intA(1) = 5
intA(2) = 9
'2の位置にある数字を表示する
Debug.Print intA(2)
'配列のサイズを変更する
ReDim Preserve intA(3)
intA(0) = 6
intA(1) = 8
'2の位置にある数字をもう一度表示する
Debug.Print intA(2)
End Sub
上記の例では、ReDim Preserveステートメントによって値が保持されているため、イミディエイトウィンドウには2回とも数字の9が表示されます。