配列は、いわば集合住宅のようなものです。1棟の建物に複数の世帯が同時に住むことが可能です。配列を使用するときは、配列の宣言時に部屋数(要素数)を指定します。
では、プログラムの実行中に、要素が増加するような場合はどうでしょう。あるいは、プログラムを作成する時点では、いくつの要素を格納するかわからないときは、どうしたらいいでしょう。そんなケースで役立つのが動的配列という使い方です。
動的配列は、宣言時に要素数を指定しません。
Sub Sample33() Dim Member() As String End Sub
一般的な配列では「Member(5)」などと要素数を指定するところを、「Member()」と括弧だけを指定します。これで、変数Memeberは配列として使用できます。ただし、この宣言時点では要素数が確定していませんので、実際には使えません。そこで、プログラムのコード中で要素数を再定義します。そのとき使うのがReDimステートメントです。
次のコードは、要素数を決めない動的配列Memberを宣言し、後で要素数に3を定義しています。
Sub Sample34() Dim Member() As String MsgBox "要素数を再定義します" ReDim Member(3) Member(1) = "tanaka" Member(2) = "yamada" Member(3) = "sato" MsgBox "1人目は" & Member(1) End Sub
ReDimステートメントは、何度でも実行できます。
Sub Sample35() Dim Member() As String MsgBox "要素数を再定義します" ReDim Member(2) Member(1) = "tanaka" Member(2) = "yamada" ReDim Member(3) Member(3) = "sato" MsgBox "3人目は" & Member(3) End Sub
上のコードは、一度「ReDim Member(2)」と要素数を再定義した配列に対して、再度「ReDim Member(3)」と要素数を変更しています。ただし、上のコードには重要な問題があります。最後のMsgBoxで「最後に定義した要素」を取り出しています。ここではMember(3の"sato"ですね。これは問題ありません。では、先頭の要素Member(1)を取り出したらどうでしょう。
Sub Sample36() Dim Member() As String MsgBox "要素数を再定義します" ReDim Member(2) Member(1) = "tanaka" Member(2) = "yamada" ReDim Member(3) Member(3) = "sato" MsgBox "1人目は" & Member(1) End Sub
結果は空欄です。最初に代入した"tanaka"が消えてしまいました。実は、消えたのは"tanaka"だけではありません。"suzuki"も"yamada"も消えています。そう、ReDimステートメントによる要素数の再定義では、それまで格納されていたデータがクリアされてしまうのです。
それでは困る場合もあります。そこで、すでに格納されているデータを消さずに、要素数を再定義する方法もあります。それには、ReDimステートメントにPreserveというキーワードを付けます。次のコードは、すでに格納されているデータを保持したままで配列の要素数を再定義します。
Sub Sample37() Dim Member() As String MsgBox "要素数を再定義します" ReDim Member(2) Member(1) = "tanaka" Member(2) = "yamada" ReDim Preserve Member(3) Member(3) = "sato" MsgBox "1人目は" & Member(1) End Sub
動的配列は、配列の要素数が変化します。配列の要素数を調べるにはLBound関数とUBound関数を使います。LBound関数は、引数で指定した配列で使用できる最も小さいインデックス番号を返します。一方のUBound関数は、引数で指定した配列で使用できる最も大きいインデックス番号を返します。
Sub Sample38() Dim Member() As String MsgBox "要素数を再定義します" ReDim Member(2) Member(1) = "tanaka" Member(2) = "yamada" ReDim Preserve Member(3) Member(3) = "sato" MsgBox LBound(Member) & vbCrLf & _ UBound(Member) End Sub
UBound関数は、バリアント型変数に配列を格納したときにもよく使います。詳しくは、下記のページをご覧ください。