VBAで覚えておくデータ構造 - 静的配列・動的配列・ディクショナリ

VBAで必要なデータ構造の覚書です。

静的配列

静的配列は複数件のデータを扱うためのデータ構造です。
静的配列では、生成時にサイズ(格納するデータの個数)を決めます。いったん静的配列を生成すると、後からサイズを変更することはできません。

■静的配列を生成する。

静的配列の生成は以下のように行います。

Dim 静的配列の名前(静的配列のサイズ) as データ型

静的配列の生成では、静的配列の名前とサイズ(格納するデータの個数−1)と格納するデータ型を指定します。VBAの場合、静的配列のサイズは実際に格納する『データの個数−1』であることに注意してください。


例えば、4個のStringを格納する静的配列sArrayを生成するには、以下のように書きます。このとき、サイズには3(=4個−1)を指定します。

Dim sArray(3) As String
■静的配列にデータを格納する。

静的配列へのデータの格納は以下のように行います。

静的配列の名前(インデックス) = データ

データの格納では、静的配列の名前とインデックスと格納するデータを指定します。
インデックスとは静的配列の位置を表す数字で、「0」以上で「静的配列のサイズ」以下の値を指定する必要があります。


例えば、静的配列sArrayにデータを格納するには、以下のように書きます。

sArray(0) = "Monday"
sArray(1) = "Tuesday"
sArray(2) = "Wednesday"
sArray(3) = "Thursday"
■静的配列からデータを取得する。

静的配列からのデータの取得は以下のように行います。

Call サブルーチン(静的配列の名前(インデックス))
変数 = 関数(静的配列の名前(インデックス))
変数 = 静的配列の名前(インデックス)
関数名 = 静的配列の名前(インデックス)

データの取得では、静的配列の名前とインデックスを指定します。インデックスの考え方はデータの格納時と同様です。
静的配列から取得したデータは、サブルーチンや関数の引数に渡したり、変数に代入したり、関数の戻り値として返したりできます。


例えば、静的配列sArrayのデータをイミディエイトウィンドウに表示するには、以下のように書きます。

Debug.Print sArray(0) => Monday
Debug.Print sArray(1) => Tuesday
Debug.Print sArray(2) => Wednesday
Debug.Print sArray(3) => Thursday
■静的配列中のすべてのデータに同じ処理をする。

静的配列中のすべてのデータに同じ処理をするためには、以下のようなFor文を使用します。

Dim i As Integer

For i = 0 To UBound(静的配列の名前)
    ' 静的配列の名前(i)を使った処理
Next

このFor文中の『UBound(静的配列の名前)』は静的配列のサイズを表します。そのため、このFor文を使えば静的配列中のすべてのデータに同じ処理を行えます。


例えば、静的配列sArrayのすべてのデータをイミディエイトウィンドウに表示するには、以下のように書きます。

Dim i As Integer

For i = 0 To UBound(sArray)
    Debug.Print sArray(i)
Next

これは以下のように書いた場合と同じ結果になります。

Debug.Print sArray(0) => Monday
Debug.Print sArray(1) => Tuesday
Debug.Print sArray(2) => Wednesday
Debug.Print sArray(3) => Thursday

動的配列

動的配列も静的配列と同様に、複数件のデータを扱うためのデータ構造です。
動的配列では、生成時にサイズ(格納するデータの個数)を決めません。生成後に必要に応じてサイズを設定します。
また、動的配列のサイズは何度でも再設定可能です。

■動的配列を生成する。

動的配列の生成は以下のように行います。

Dim 動的配列の名前() as データ型

動的配列の生成では、動的配列の名前と格納するデータ型を指定します。なお、生成時にサイズは指定しません。


例えば、Stringを格納する動的配列dArrayを生成するには、以下のように書きます。

Dim dArray() As String
■動的配列のサイズを設定する。

動的配列のサイズの設定は以下のように行います。

ReDim Preserve 動的配列の名前(動的配列のサイズ)

サイズの設定では、動的配列の名前とサイズ(格納するデータの個数−1)を指定します。VBAの場合、動的配列のサイズは実際に格納する『データの個数−1』であることに注意してください。
なお、動的配列のサイズは何度でも再設定できます。


例えば、4個のデータを格納できるように動的配列のサイズを設定するには、以下のように書きます。このとき、サイズには3(=4個−1)を指定します。

ReDim Preserve dArray(3)
■動的配列にデータを追加する。

動的配列へのデータの格納は、静的配列と同様に、以下のように行います。

動的配列の名前(インデックス) = データ

データの格納では、動的配列の名前とインデックスと格納するデータを指定します。
インデックスとは動的配列の位置を表す数字で、「0」以上で「動的配列のサイズ」以下の値を指定する必要があります。


例えば、動的配列dArrayにデータを格納するには、以下のように書きます。

dArray(0) = "January"
dArray(1) = "February"
dArray(2) = "March"
dArray(3) = "April"
■動的配列からデータを取得する。

動的配列からのデータの取得は、静的配列と同様に、以下のように行います。

Call サブルーチン(動的配列の名前(インデックス))
変数 = 関数(動的配列の名前(インデックス))
変数 = 動的配列の名前(インデックス)
関数名 = 動的配列の名前(インデックス)

データの取得では、動的配列の名前とインデックスを指定します。インデックスの考え方はデータの格納時と同様です。
動的配列から取得したデータは、サブルーチンや関数の引数に渡したり、変数に代入したり、関数の戻り値として返したりできます。


例えば、動的配列dArrayのデータをイミディエイトウィンドウに表示するには、以下のように書きます。

Debug.Print dArray(0) => January
Debug.Print dArray(1) => February
Debug.Print dArray(2) => March
Debug.Print dArray(3) => April
■動的配列中のすべてのデータに同じ処理をする。

動的配列中のすべてのデータに同じ処理をするためには、以下のようなFor文を使用します。

Dim i As Integer

For i = 0 To UBound(動的配列の名前)
    ' 動的配列の名前(i)を使った処理
Next

このFor文中の『UBound(動的配列の名前)』は動的配列のサイズを表します。そのため、このFor文を使えば動的配列中のすべてのデータに同じ処理を行えます。


例えば、動的配列dArrayのすべてのデータをイミディエイトウィンドウに表示するには、以下のように書きます。

Dim i As Integer

For i = 0 To UBound(dArray)
    Debug.Print dArray(i)
Next

これは以下のように書いた場合と同じ結果になります。

Debug.Print dArray(0) => January
Debug.Print dArray(1) => February
Debug.Print dArray(2) => March
Debug.Print dArray(3) => April

ディクショナリ

ディクショナリは、キーに関連付けてデータを格納するデータ構造です。

■※Microsoft Scripting Runtimeの参照設定

Microsoft Scripting Runtime」への参照設定を行うと、ディクショナリで使用可能なプロパティとメソッドを入力候補として表示できるため便利です。


参照設定をするには、まずVisual Basic Editorのメニューの[ツール]-[参照設定...]を選びます。参照設定ダイアログが表示されるので、ダイアログのリストボックス中にある[Microsoft Scripting Runtime]にチェックを入れます。その後、ダイアログの[OK]ボタンをクリックすれば、参照設定は完了です。
参照設定を行うと、ディクショナリを格納するためのScripting.Dictionary型の変数を宣言できます。

Dim 変数名 As Scripting.Dictionary

「変数名.」と入力してから「Ctrl+Space」を押すと、ディクショナリで使用可能なプロパティとメソッドが入力候補として表示されます。


なお、参照設定を行わない場合、ディクショナリを格納する変数にはVariant型を使用します。

Dim 変数名 As Variant

この場合、入力候補の表示はできません。

■ディクショナリを生成する。

ディクショナリの生成は以下のように行います。

Set ディクショナリの名前 = CreateObject("Scripting.Dictionary")

ディクショナリの生成では、ディクショナリの名前を指定します。


例えば、ディクショナリdictを生成するには、以下のように書きます。

Set dict = CreateObject("Scripting.Dictionary")
■ディクショナリにデータを格納する。

ディクショナリへのデータの格納は以下のように行います。

ディクショナリの名前(キー) = データ

データの格納では、ディクショナリの名前とキーと格納するデータを指定します。データはキーに関連付けて格納されます。


例えば、ディクショナリdictにデータを格納するには、以下のように書きます。

dict("name") = "練馬"
dict("population") = 712783
dict("song") = "わが街・練馬"
■ディクショナリからデータを取得する。

ディクショナリからのデータの取得は以下のように行います。

Call サブルーチン(ディクショナリの名前(キー))
変数 = 関数(ディクショナリの名前(キー))
変数 = ディクショナリの名前(キー)
関数名 = ディクショナリの名前(キー)

データの取得では、ディクショナリの名前とキーを指定します。キーに関連づいたデータが取得されます。
ディクショナリから取得したデータは、サブルーチンや関数の引数に渡したり、変数に代入したり、関数の戻り値として返したりできます。


例えば、ディクショナリdictのデータをイミディエイトウィンドウに表示するには、以下のように書きます。

Debug.Print dict("name") => 練馬
Debug.Print dict("population") => 712783
Debug.Print dict("song") => わが街・練馬
■ディクショナリ中のすべてのデータに同じ処理をする。

ディクショナリ中のすべてのデータに同じ処理をするためには、以下のようなFor Each文を使用します。

Dim key As Variant
Dim data As Variant

For Each key In dict
    data = ディクショナリの名前(key)
    
    Debug.Print key & ": " & data
Next

このFor Each文では、すべてのキーとデータについて処理を繰り返します。繰り返すたびに変数keyにキーが、変数dataにデータが格納されます。


例えば、ディクショナリdict中のすべてのキーとデータの関連付けをイミディエイトウィンドウに表示するには、以下のように書きます。

Dim key As Variant
Dim data As Variant

For Each key In dict
    data = dict(key)
    
    Debug.Print key & ": " & data
Next

これは、以下のように書いた場合と同じような結果になります。ただし、キーの順序は決まっていないので、表示順序は異なることがあります。

Debug.Print "name: " & dict("name") => name: 練馬
Debug.Print "population: " & dict("population") => population: 712783
Debug.Print "song: " & dict("song") => song: わが街・練馬