VBAの配列まとめ(静的配列、動的配列)
VBAで配列を必要とするのは、処理速度を上げる為だと言って良いでしょう。
そもそも、エクセルにはセルの2次元配列であるシートがあります。
にもかかわらず、VBAの学習を進めると必ず配列が出てきます。
セルを使うと処理速度が非常に遅く、これを高速に処理するために配列が必要となるからです。
配列を一括でシートに出力することで、高速に動作するVBAを実現することが出来ます。
VBAで配列を使いこなせるようになることは、VBA習得の1つの大きな目標と言えます。
以下の項目に分けて解説します。
配列の概念
集合住宅やアパートにたとえられますが、
要は、変数の箱を複数つなげたものと理解すれば良いでしょう。
結果として、複数の値をいれられるのが配列という事になります。
通常の変数が、1つの変数に1つの値を格納している点で大きく異なっています。
配列のインデックス番号(配列内の位置)を指定することで、個々の要素を参照することもできます。
これを、
Option Base 1
これをモジュールの宣言セクションに指定することで、
インデックスの最小値を1に変更可能ですが、あまり使用しない方が良いと思っています。
VBA内で、必要に応じて箱の数を変更する場合があります。
箱の数を固定せずVBAで動的に変更するのを、動的配列と呼びます。
プログラミングをする上で、
実行時点で要素数を決めたい場合や、実行途中で増やしたい場合が多くあります。
実行時点で要素数を増減できる動的配列こそが配列の極みになります。
静的配列
配列の宣言
上記の宣言で、11個要素を持つ、1次元の配列を定義したことになります。
値を入れる時は、
以下の例では、配列に0から10を順に数値を入れています。
Sub sample()
Dim MyArray(10) As Long
Dim i As Long
For i = 0 To 10
MyArray(i) = i
Next
End Sub
多次元配列
ワークシートの、11行、6列のセル範囲を想像してもらえればよいでしょう。
Sub sample()
Dim MyArray(10, 5) As Long
Dim i As Long, j As Long
For i = 0 To 10
For j = 0 To 5
MyArray(i, j) = Cells(i + 1, j + 1)
Next
Next
End Sub
上記では、セル範囲A1~F11を配列に入れています。
要素の下限の変更
特に、ワークシートとデータのやり取りをする場合は、
このようにした方が、理解しやすく、また、記述もしやすいでしょう。
動的配列
ReDimステートメント
Preserve |
省略可能です。 |
varname |
必ず指定します。 |
subscripts |
必ず指定します。 |
type |
省略可能です。 |
キーワード Preserve を指定した場合、変更できるのは動的配列の最後の次元のサイズに限られます。
つまり、キーワードPreserveを使用した場合、動的配列のサイズを変更するために変えられるのは、添字の上限だけです。
また、次元数は変更できません。
添字の下限を変更しようとすると、エラーが発生します。
また、バリアント型 (Variant) 変数は Empty 値に初期化されます。
要素数の変更について
ReDim MyArray(10, 10)
↓
ReDim MyArray(10)
↓
ReDim MyArray(10, 10)
このように、Redimで次元も要素数も変更できます。
ただし、Redimにより、それまでに配列に入っていた値は失われます。
Preserveを指定します。
ReDim MyArray(10, 10)
↓
ReDim Preserve MyArray(10, 11)
↓
ReDim Preserve MyArray(11, 11)
Preserveを指定することで、値がそのまま残ります。
しかし、制限があります。
Preserveを指定した場合は、動的配列の最後の次元のサイズのみ変更可能で、
それより上位の次元は変更できません、エラーとなります。
次元数の最大値は60とはなっていますが、
通常は、2次元までにしましょう。
ワークシートが2次元なのですから、大抵の処理は2次元で済むはずです。
それ以上の次元は、むやみにVBAを複雑化させるだけです。
セル範囲⇔配列の基本
また、配列をセル範囲にまとめて入れる事も出来ます。
Dim MyArray
MyArray = Range("A1:B100")
・・・処理・・・
Range("A1:B100") = MyArray
MyArray = Range("A1:B100")
セル範囲⇔配列使用例
速度の違いは、一目瞭然ですので、実際にやってみて下さい。
Sub sample1()
Dim i As Long
Application.ScreenUpdating = False
For i = 1 To 100000
Cells(i, 3) = Cells(i, 1) * Cells(i, 2)
Next
Application.ScreenUpdating = False
End Sub
Sub sample2()
Dim i As Long
Dim MyArray1
Dim MyArray2
MyArray1 = Range("A1:B100000")
ReDim MyArray2(1 To 100000, 1 To 1)
For i = LBound(MyArray1, 1) To UBound(MyArray1, 1)
MyArray2(i, 1) = MyArray1(i, 1) * MyArray1(i, 2)
Next
Range("C1:C100000") = MyArray2
End Sub
単に、100,000行の掛け算をしています。
上記で、
ReDim MyArray2(1 To 100000, 1 To 1)
1次元目が行、2次元目が列に相当します。
LBoundは、0でも問題ありませんが、1にした方が理解しやすいと思います。
配列で必要となるVBA関数とステートメント
LBound関数
arrayname | 必ず指定します。 配列変数の名前です。 変数の標準的な名前付け規則に従って指定します。 |
dimension | 省略可能です。 バリアント型 (内部処理形式 Long の Variant) の値を指定します。 添字の最小値を調べる対象となる配列の次元を示す整数を指定します。 最初の次元なら 1、2 番目の次元なら 2、というように指定します。 引数 dimension を省略すると、1 が指定されたものと見なされます。 |
UBound関数
arrayname | 必ず指定します。 配列変数の名前です。 変数の標準的な名前付け規則に従って指定します。 |
dimension | 省略可能です。 バリアント型 (内部処理形式 Long の Variant) の値を指定します。 添字の最小値を調べる対象となる配列の次元を示す整数を指定します。 最初の次元なら 1、2 番目の次元なら 2、というように指定します。 引数 dimension を省略すると、1 が指定されたものと見なされます。 |
LBound関数、UBound関数の使用例
For i = LBound(MyArray, 1) To UBound(MyArray, 1)
For j = LBound(MyArray, 2) To UBound(MyArray, 2)
MyArray(i, j) = 0
Next
Next i
上記では、2次元配列MyArrayの全次元の全要素に0を入れています。
Array関数
引数 arglist には、値のリストをカンマ (,) で区切って指定します。
引数 arglist を指定しない場合は、長さ 0 の配列が作成されます。
Dim MyArray
MyArray = Array(10, 20, 30)
この結果、MyArrayは、
IsArray関数
IsArray 関数は、特に配列を含むバリアント型 (Variant) の式 に有効です。
Join関数
sourcearray | 必ず指定します。 結合する文字列を含む 1 次元配列を指定します。 |
delimiter | 省略可能です。戻り値となる文字列を区切るのに使用する文字を指定します。 省略すると、スペース (" ") が使用されます。 引数 delimiter が長さ 0 の文字列 (") である場合は、リスト内のすべての項目が区切り文字なしで連結されます。 |
Filter関数
sourcearray |
必ず指定します。 |
match |
必ず指定します。 |
include |
省略可能です。 |
compare |
省略可能です。 |
引数 sourcearray 内で引数 match に一致する文字列がなかった場合は、Filter 関数は空の配列を返します。
引数 sourcearray が Null 値であるか、1 次元配列でない場合は、エラーになります。
Filter 関数が返す配列は、一致した項目数分だけの要素が含まれています。
Eraseステートメント
静的数値配列 | 要素はすべて 0 に設定されます。 |
静的文字列配列 (可変長) | 要素はすべて長さ 0 の文字列 (") に設定されます。 |
静的文字列配列 (固定長) | 要素はすべて 0 に設定されます。 |
静的バリアント型 (Variant) 配列 | 要素はすべて Empty 値に設定されます。 |
ユーザー定義型配列 | 各要素は、別個の変数として設定されます。 |
オブジェクト配列 | 要素はすべて特別な値 Nothing に設定されます。 |
配列に関する記事の一覧
1次元配列の並べ替え(バブルソート,クイックソート)
同じテーマ「マクロVBA技術解説」の記事
配列の使い方について
VBAの配列まとめ(静的配列、動的配列)
最終行の判定、Rangeオブジェクトと配列、高速化の為に
記述による処理速度の違い
速度比較決定版【Range,Cells,Do,For,ForEach】
エクセルVBAのパフォーマンス・処理速度に関するレポート
VBAのFindメソッドの使い方には注意が必要です
マクロVBAの高速化・速度対策の具体的手順と検証
動的2次元配列の次元を入れ替えてシートへ出力(Transpose)
大量データで処理時間がかかる関数の対処方法(SumIf)
大量データにおける処理方法の速度王決定戦
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
- ホーム
- マクロVBA応用編
- マクロVBA技術解説
- VBAの配列まとめ(静的配列、動的配列)
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。