VBA配列基礎
通常の変数は1つの変数に1つの値しか格納できませんが、配列を利用すれば一つの変数に同じデータ型の複数の値を格納することができます。このエントリーでは、VBAで配列を利用するための基本事項をご紹介致します:)
配列とは
まず、配列とは何かを知っておきましょう:)
配列の定義
VBA のヘルプには以下のようにあります。
配列
定義済みの同じデータ型を持つ要素の集合。各要素には順番にインデックス番号が付けられます。各要素を識別するには、配列名とインデックス番号を使います。ある要素に変更を加えても、他の要素には影響しません。
冒頭でも述べましたが、配列は一つの変数に複数の値を保持します。配列に含まれる値はそれぞれ『要素』と呼ばれます。各要素には『インデックス番号』が割り振られ、対応する『インデックス』を指定して参照することができます。インデックスは通常『0』から始まります。一つ目の要素は『要素0』、ふたつ目の要素は『要素1』といった感じです。配列を構成している要素の数を『要素数』と表現します。
どんなとき使うの?
ではこの配列はいったいどんな状況で使うのでしょうか?
例えば、1ヶ月分の天気を管理するプログラムがあったとします。『一日は晴れ』『二日はくもり』のように31日分の天気を格納しなければならないため、配列を使用しないと31個もの変数を定義しなければなりません。これは定義するだけでも大変ですし、データの取り扱いも難しくなってしまいます。
こんなプログラム考えただけでも触りたくないですよね...
一方、配列を使えば変数の宣言はひとつだけです。データの取り扱いもインデックスを使って簡単に行えます。
'天気情報変数定義 Dim weather01 As String Dim weather02 As String Dim weather03 As String ・・・ Dim weather31 As String
'天気情報変数定義 Dim weather(30) As String
上記の例をご覧頂ければ一目瞭然ですが、配列を使用することによってだいぶスッキリしているのがわかります。
このように、例に挙げた『1ヶ月の天気』のような同じデータ型の繰り返しの項目を取り扱う時に配列はその効果を発揮します。
※カッコ内の数字はインデックス番号
定義などの詳細は後述します:)
配列の次元
配列には『次元』という概念があります。
先ほどの1ヶ月分の天気を管理するプログラムを例に見てみると、純粋に日にちの繰り返しだけなので『一次元配列』となります。
では1年分の天気を管理するにはどうしたらいいでしょうか。
1ヶ月分であれば要素数31の配列があれば事足りますが、1年分となると1ヶ月の配列が12個、つまり『12(月数)×31(日数)』の要素が必要になります。このような『繰り返し×繰り返し』の性質を持つ配列を総じて『多次元配列』といいます。言わば『配列の配列』です。例に挙げた1年分の天気なら『二次元配列』ですね。これが複数年、例えば5年分の天気を管理するとなると 『5(年数)×12(月数)×31(日数)』となるので『三次元配列』となります。
※カッコ内の数字はインデックス番号
静的配列と動的配列
VBAで宣言できる配列は静的配列と動的配列の2種類に大別されます。まずはこの2つをしっかりと理解しておきましょう。
静的配列とは
静的配列とは、配列変数宣言時にその要素数も同時に宣言し、宣言後は要素数を変更できない配列の事を言います。つまり、初めに「要素数3」と定義したら後から要素数を5に増やしたり、逆に2に減らしたりできないって事です。なお、VBAのヘルプでは静的配列を「固定長配列」と表現していることもありますが、このエントリーでは「静的配列」で統一しています。
静的配列を宣言する際のリファレンスです。
構文:{ Dim | Static | Public | Private } arrayname ([lowerbound to ] upperbound [,[lowerbound to ] upperbound...]) [As type]
指定項目 | 指定 | 内容 |
arrayname | 必須 | 配列変数の名前を指定します。 |
lowerbound | 省略可 | 配列の下限を明示的に定義する場合に指定します。省略した場合は、Option Baseステートメントで指定した0または1が配列の下限となります。Option Baseの宣言がない場合は0が配列の下限となります。 |
upperbound | 必須 | 配列の上限を指定します。多次元配列を定義する場合は [lowerbound To] upperbound の形式をカンマで区切って次元数分定義します。 |
type | 省略可 | 通常の変数と同じように配列変数の型を指定します。 |
以下に静的配列を宣言するサンプルを示します。変数名のあとに要素の下限・上限をカッコ付きで記述します。
'要素数4(0,1,2,3)のString型の配列定義 Dim array1(3) As String '要素数3(2,3,4)のLong型の配列定義 Dim array2(2 To 4) As Long '要素数3,2の2次元配列定義 Dim array3(2, 1) As Long
動的配列とは
動的配列とは、配列変数宣言時に要素数を明示的に宣言せず、宣言後に配列の要素数を動的に変更することができる配列です。動的配列の要素数は後述のReDimステートメントで再定義します。
動的配列を宣言する際のリファレンスです。
構文:{ Dim | Static | Public | Private } arrayname () [As type]
指定項目 | 指定 | 内容 |
arrayname | 必須 | 配列変数の名前を指定します。 |
type | 省略可 | 通常の変数と同じように配列変数の型を指定します。 |
以下に動的配列を宣言するサンプルを示します。静的配列と違い要素数(カッコの中の数字)を定義せず、変数名のあとには空のカッコのみ記述します。
'要素数(下限・上限)を宣言しない Dim array1() As String Dim array2() As Long
ReDimステートメント
要素数を省略して定義された動的配列はReDimステートメントを使用して下限・上限、次元を再定義しメモリ領域の再割り当てを行います。
ReDimステートメントは以下の構文で使用します。Preserveキーワード以外は静的配列の構文と同じですね。
構文:ReDim [Preserve] arrayname ([lowerbound to ] upperbound [,[lowerbound to ] upperbound...]) [As type]
指定項目 | 指定 | 内容 |
preserve | 省略可 | 要素数を変更する際に、配列に格納されている値を保持したままにする場合に指定します。 |
arrayname | 必須 | 配列変数の名前を指定します。 |
lowerbound | 省略可 | 配列の下限を明示的に定義する場合に指定します。省略した場合は、Option Baseステートメントで指定した0または1が配列の下限となります。Option Baseの宣言がない場合は0が配列の下限となります。 |
upperbound | 必須 | 配列の上限を指定します。多次元配列を定義する場合は [lowerbound To] upperbound の形式をカンマで区切って次元数分定義します。但し、ReDimステートメントで上限を変更できるのは最後の次元のみです。 |
type | 省略可 | 通常の変数と同じように配列変数の型を指定します。 省略した場合は変数宣言時のデータ型になります。 |
以下にRedimステートメントを使用するサンプルを示します。
'String型の動的配列を宣言 Dim aryDynamic() As String 'Redimで配列を再定義 ReDim aryDynamic(3) As String 'Redimで2次元配列を再定義 ReDim aryDynamic(3, 3) As String
値の格納と参照
静的配列と動的配列を理解したところで、実際に配列を使用してイメージを掴んでみましょう:)
配列は複数の値を保持できます。それぞれの値の格納・参照はインデックスを使用して行います、↓こんな感じに。
'要素数3(0,1,2)の配列を宣言 Dim aryStatic(2) As String 'インデックスを使用して値を格納 aryStatic(0) = "ラス" aryStatic(1) = "ペニー" aryStatic(2) = "白チョコ" '参照する場合もインデックスを使用 Debug.Print "要素0:" & aryStatic(0) Debug.Print "要素1:" & aryStatic(1) Debug.Print "要素2:" & aryStatic(2)
このコードを実行するとイミディエイトウィンドウには以下のように表示されます。
要素1:ペニー
要素2:白チョコ
配列を参照する場合はFor Nextステートメント、通称Forループを使用する事が多いです。以下のコードを実行すると先ほどと同じ内容がイミディエイトウィンドウに出力されます。
'Forループで参照 Dim i As Long For i = 0 To 2 Debug.Print "要素" & i & ":" & aryStatic(i) Next
例では静的配列を使用しましたが、動的配列でも格納・参照の方法は同じです。
値を保持するPreserveキーワード
ReDimステートメントで動的配列を再定義すると、それまで配列の内容はクリアされてしまいます。
以下の例では要素数3の動的配列aryDynamicに値を格納した後、ReDimステートメントを使用して要素数を4に拡張しまいます。Preserveキーワードの有無で値がクリアされるか保持されるかの違いがわかります。
▼1つ目のStopの時点では値が格納されています
▼ReDimで配列を拡張するとそれまで格納されていた値がクリアされてしまう
Preserveキーワードを指定すれば値をクリアすることなく配列を拡張することができます。
▼Preserveキーワードを指定すると値を保持したまま配列を拡張できる
配列に必要なメモリ容量
まず、配列は要素数、データ型に関わらず20バイトのメモリを必要とします。さらに、次元ごとに4バイトのメモリを必要とします。それぞれの要素についてはデータ型に必要なメモリ容量が要素数分必要です、、、って、自分で書いててもわかりづらい事この上ないですね(^^;
要するに、配列に必要なメモリ容量は以下の数式で求めることができます。
例えば、要素数3のLong型の1次元配列は
=20 + (4) + (12)
=36バイト
となります。
1次元目の要素数が3、2次元目の要素数が10のInteger型の2次元配列は
=20 + (8) + (26)
=54バイト
となります。
まとめ。
配列はプログラミングに置いてとても重要で、ある程度の規模のプログラムになると必ずと言っていい程配列が登場します。
特に Excel のワークシートは行・列の二次元配列なので、Excel VBA では特に重要です。このエントリーで述べていることは配列の基礎の基礎になりますのでしっかりと理解して配列を使いこなしましょう:)
ご不明点などありましたらお気軽にお問合せくださいまし:D
HAYs
コメントを残す