ExcelVBA(マクロ)で配列変数を作る方法/ReDim、Preserve、Option Baseステートメント、Array、UBound、LBound関数の使い方

village IT

他のプログラミング言語同様、VBAにも配列を作る機能が用意されています。ここでは配列作成の基本および補足機能について解説しています。
変数の作成方法についてはDimの記事で解説していますので、併せてご参照ください。

Advertisements

配列とは/配列変数の作り方

配列変数の宣言
Dim 変数名(最大値) As データ型
※データ型を省略した場合Variant型になる
array3
まず普通の変数から。
この例では似たようなデータみっつをそれぞれ別の変数として宣言して、それぞれに値を入れ込んでいます。
array1
この変数1、2、3を、変数名(1)、変数名(2)、変数名(3)のように同じ変数名と番号で表現したものが配列変数です。
array2
変数(番号)にはそれぞれ値を入れ込んでいくことができます。
配列とは番号で区切られたそれぞれ異なるデータの集合体です。今まで別々の封筒に入れていたデータを、仕切りで区切ったひとつの引き出しにまとめたような状態です。
array4
「どの配列変数の」「何番目」を指定することで、普通の変数同様に値を取りだすことができます。
array5
配列変数名右の()内の数値をインデックス番号といいます。インデックス番号の最低値はデフォルトで0となり、宣言時()内に入力した数字が最大値となります。最低値から最大値の間分だけ配列変数を作成することができます(整数のみ)。
0,1,2,3なので、最低値が0で最大値が3の場合、4つの配列変数を作ることができます。
array6
インデックス番号の有効範囲を超える配列変数を作ろうとすると、このようにエラーが出ます。
array7
Variant型で配列変数を作れば、どんなデータ型でも収納することができます。
表はデータを順々に出力した例です。For nextで配列変数を順番に出力する場合、インデックス番号を0からカウントしているのであれば、変数名(i – 1)のように指定する必要があります。
' vba
Dim 配列(3)
Dim i As Integer
配列(0) = "A"
配列(1) = 12345
配列(2) = #1/1/2020#
For i = 1 To 3
Cells(i, 1).Value = 配列(i - 1)
Next

配列変数の最低値を0から1にする(Option Base)

インデックス番号の最低値の変更
Option Base 最低値
※0か1のみ設定可能
array8
特に指定しない場合配列の最低値は0ですが、宣言モジュールでOption Base 1と記入することで、最低値を1に変更することができます。2以上の値は設定できません。
array9
先ほどのコードを実行すると、変数名(0)を指定した場合エラーが出るようになります。
最大値は変わらない(3のまま)なので、配列内に格納できる数値は0~3の4つから1~3の3つになります。
array10
配列を0~2から1~3に変更してあげます。
array11
この状態ならiもいちいち-1する必用がなくなり、より直感的に配列を使用することが可能となります。
(ちなみにOption Baseを噛ませないでも(0)を作らず、配列変数(1)から(3)までだけ指定することもできます)。

インデックス番号の最低値と最大値を同時に指定

array12
配列変数の宣言時に変数名(最低値 to 最大値)と入力することで、変数の最低値と最大値を同時に指定することができます。
array13
この宣言はOption Baseより優先されます。
たとえば図ではOption Baseで1を設定後、変数の宣言で最低値を0に設定し、インデックス番号が0の変数を作成していますが、問題なく動きます。

変数に配列を代入/Array関数の使い方

ここまでは「配列変数を先に宣言して、変数に値をそれぞれ代入」というやりかたを見てきましたが、Array関数では「変数を宣言して、そこに値の入った配列をセットで代入」というやりかたをします。

引数の値を配列にして返す
Array (要素1,要素2,要素3…)
※データ型はVariant型固定
array14
Array関数で配列変数を作ってみましょう。
まずインデックス番号を指定せずに変数を作ります。
array15
この変数に対し = を付け、その後にArrayを置き、
array16
配列として代入したい要素を,で区切って列挙します。この場合3つ記入しているので、自動的に配列変数が3つ作成されます。
array17
実行すると、ちゃんと配列変数になっていることがわかります。
array18
Array関数で作る配列はデータ型がVariant固定なので、それを代入する変数もVariantにして下さい(特にデータ型指定しなければ自動でなります)。
array19
それ以外のデータ型の変数に代入しようとするとエラーになります。
array20
Array関数の引数内のデータを増やせば、配列変数の数も自動で増えます。
array21
このコードで言えば、繰り返しの回数が配列変数の数とズレてるとエラーになるので、繰り返しの回数を1増やします(For i = 1 to 34)。
For Nextと配列変数をセットで使う場合、インデックス番号廻りを変更したら基本こういう修正がセットになります。
array22
Array関数で作った配列変数はArray関数で上書きすることが可能です。
array23
配列変数の数を変更することも可能です。この場合4つから3つに変更しているので、繰り返しを1減らします。
値ではなく配列変数をセットで変数に代入するイメージです。この場合配列(4)という配列変数は消滅し、参照できなくなります。しようとするとエラーになります。

動的配列の作成(ReDim)

array24
変数名(インデックス番号)という形で作った変数は、上限値が固定に(静的に)なります。これを静的配列と呼び、これに対し上限値が可変の配列を動的配列と呼びます。
とりあえず作ってみます。Dim 変数名()と記入し、インデックス番号を指定しなければ動的配列を作ることができます。この時点で上限値が設定されていないので、配列変数には何も代入できません。データ型を指定する時はDimで行います。
array25
上限値を設定するには同じ動的配列変数に対し、ReDim 変数名(最大値)と記入します。
動的配列変数の宣言
Dim 変数名() As データ型
※データ型を省略した場合Variant型になる

動的配列変数の最大値の変更
ReDim 変数名(最大値)
※データ型は変更不可

array26
後はいつもの感じです。
array27
プロシージャの途中で最大値を変更することも可能です。
array32
一点注意点として、動的配列にRedimをかけて最大値を変更すると、元から変数に格納されていた値は全てクリアされます。
例としてRedimで最大値を変更し、
array33
その後動的配列(0)~(5)までを2行目に出力すると、
array34
このようになります。
array35
2回目のRedimをかけた時点で動的配列(0)~(3)の値がクリアされているので、2行目に出力されていないことが確認できます。

Redim実行時に元の値を保持(Preserve)

array36
もしRedimをかける時に元の値を残したい場合は、ReDim Preserve 変数名(最大値)のように記述します。
元の値を保持して動的配列変数の最大値の変更
ReDim Preserve 変数名(最大値)
※データ型は変更不可
array37
実行すると、インデックス番号の上限を変更しても元の値が保持されていることが確認できます。
array38
ただしPreserveを使っても、インデックス番号の枠から外れた配列変数の値は破棄されます。
ここでは元々4つある配列変数を3つ→4つと変更し、値を出力しています。
array39
実行すると、上限を下げた時点で一度枠外に出た配列変数の値が破棄されていることが確認できます。

配列の上限、下限、作成可能数を調べる(LBound、UBound関数)

配列変数の下限値を調べる
LBound(変数名)

配列変数の上限値を調べる
UBound(変数名)

array28
配列変数にLBound関数を噛ませると、配列の下限値を調べることができます。
この場合デフォルト値の0が下限値で、つまり動的配列(0)が指定出来る最も小さなインデックス番号となります。
array30
同様にUBound(変数名)で配列の上限値を調べることができます。
Redimで指定している通り、3が上限値となります。
array31
上限値-下限値+1が、実際に作れる配列の数となります。
' vba
Dim 動的配列() As String
ReDim 動的配列(3)
' 中略
Cells(2, 2).Value = LBound(動的配列) ' 下限値
Cells(3, 2).Value = UBound(動的配列) ' 上限値
' 作成可能な配列変数の数
Cells(4, 4).Value = UBound(動的配列) - LBound(動的配列) + 1
やりたいことから方法を探すエクセルExcel操作・関数・VBA(マクロ)逆引きまとめ
逆引き(やりたいことから探す)Excel記事まとめ
関数・演算子・メソッド・プロパティ名から探すExcel/VBA(マクロ)使い方・組み合わせ方まとめ
こちらはExcelやメソッドの諸機能を、機能の名称から探せるまとめ記事です。

コメント