VBA配列の使い方完全ガイド|宣言・初期化から高速化、エラー対策まで
導入
「Excelマクロの処理、遅すぎて焦ったことありませんか?
私たちも現場で『セルへのアクセスがボトルネックだよ。VBAの配列を使えば一括処理できて爆速になる』とアドバイスされる場面、よくあります。
- そもそもVBAでの配列の書き方がわからない…
- PythonのリストやJavaの配列と何が違うの?
- 本当に速くなるの?具体的なコードが見たい!
こんな疑問や不安、身に覚えありませんか?
今回は「配列って何?」「どう使うの?」から、業務で実際に困った時にすぐ使えるサンプルコード・ハマりポイントの解決策まで、現場目線で一緒に整理します。
(Excelマクロの実践的な使い方については『SES現場でVBAできますか?未経験向けExcelマクロ実践術』もご参照ください)
用語解説:Excelマクロ
Excelの操作を自動化するためのプログラム。VBA(Visual Basic for Applications)で記述し、繰り返し作業や大量データ処理を効率化できる。用語解説:VBA(Visual Basic for Applications)
Microsoft Office製品で使えるプログラミング言語。ExcelやAccessなどの操作を自動化できる。用語解説:配列
複数の値をまとめて管理できるデータ構造。Excelマクロでは大量データの一括処理に活用される。用語解説:Pythonのリスト/Javaの配列
Pythonのリストは可変長で型混在可、Javaの配列は固定長で型指定必須。VBA配列は宣言や拡張方法が異なるので注意。
なぜVBA配列で“爆速”になる?仕組みを図解で理解
なぜ配列を使うと速くなるの?
実はセル単位アクセスは、倉庫(Excelシート)と作業場(VBA)の間を毎回往復しているイメージ。往復(通信)が多いほど遅くなります。
一方、配列を使えば「まとめて箱詰め」して一気に作業場(メモリ)で処理し、終わったら一括で戻すだけ。通信コストが劇的に減ります。
- セル個別アクセス:VBA → セルA1 → VBA → セルA2 → … (毎回通信)
- 配列で一括処理:VBA → 全セルを一括読込 → メモリ処理 → 一括書込(たった2回の通信)
ポイントは「Excelとやりとりする回数を極限まで減らすこと」。これが配列による高速化の本質です。
(VBA×AIによるExcel高速化・CSV変換については『VBA×AIでExcelシート情報伝達率98%!CSV変換・ワイヤーフレーム出力の全手順』もご参照ください)
用語解説:セル単位アクセス
Excelの各セルに1つずつアクセスして値を取得・設定する方法。大量データでは処理が遅くなりやすい。用語解説:メモリ処理
一度にデータを配列としてメモリ上に読み込み、まとめて計算・編集する方法。Excelとのやりとり回数が減り高速化できる。
コピペで学ぶ!VBA配列の基本操作(宣言・初期化・ループ)
配列は静的配列と動的配列の2種類があります。実際の使い分けと注意点、現場の“あるある”も交えて解説します。
用語解説:静的配列
宣言時に要素数(サイズ)が決まっている配列。途中でサイズ変更はできない。用語解説:動的配列
必要に応じてサイズを変更できる配列。ReDimで拡張・縮小が可能。用語解説:Variant型
VBAで最も柔軟な型。数値・文字列・配列など何でも格納できる。セル範囲の一括読込にも使われる。用語解説:LBound/UBound
配列の最小(LBound)・最大(UBound)インデックスを取得する関数。ループ処理の安全設計に必須。
静的配列:要素数が決まっている場合
' Option Base 1 'モジュールの先頭で1始まりにできる
Sub StaticArrayExample()
' 要素数3のString型配列(インデックスは0,1,2)
Dim names(2) As String
names(0) = "佐藤"
names(1) = "鈴木"
names(2) = "高橋"
For i = LBound(names) To UBound(names)
Debug.Print names(i)
Next i
' Array関数の省略例
Dim fruits As Variant
fruits = Array("りんご", "バナナ", "みかん")
Debug.Print fruits(0)
End Sub
Python/Java経験者向け注記:
VBAの配列はデフォルト0始まり。Option Base 1で1始まりに変更可能。ただし例外もあるので、LBound/UBoundを使ったループが安全です。
動的配列:途中で要素数を変えたい場合
Sub DynamicArrayExample()
Dim scores() As Long
ReDim scores(2)
scores(0) = 80: scores(1) = 95: scores(2) = 72
ReDim Preserve scores(4)
scores(3) = 100: scores(4) = 88
For Each score In scores
Debug.Print score
Next score
End Sub
- ReDim Preserveでサイズ拡張可能。ただし、何度も拡張するとパフォーマンス低下に注意。
多次元配列:行×列の表形式
Sub MultiDimArrayExample()
Dim matrix(2, 1) As String
matrix(0, 0) = "商品A": matrix(0, 1) = "100円"
matrix(1, 0) = "商品B": matrix(1, 1) = "200円"
matrix(2, 0) = "商品C": matrix(2, 1) = "150円"
Debug.Print matrix(1, 0) & "の価格は" & matrix(1, 1)
End Sub
実践!セル範囲と配列で“爆速”一括処理
1セルずつアクセスするコード、遅すぎて実用にならない…
そう感じたら、配列の“爆速化パターン”を試しましょう。
Before(遅い)
Sub SlowProcess()
For i = 1 To 100000
Sheet1.Cells(i, "B").Value = Sheet1.Cells(i, "A").Value * 2
Next i
End Sub
After(速い!)
Sub FastProcess()
Dim data As Variant
data = Sheet1.Range("A1:B100000").Value
For i = 1 To UBound(data, 1)
data(i, 2) = data(i, 1) * 2
Next i
Sheet1.Range("A1:B100000").Value = data
End Sub
この黄金パターンを覚えてください。
「①一括読込 → ②メモリ処理 → ③一括書込」だけで100倍速くなることも。
インデックスエラー対策:5つの“落とし穴”と安全設計
『インデックスが有効範囲にありません』
原因は大きく5つ。現場でよくある失敗パターンと対策コードをセットで整理します。
1. 動的配列でReDimし忘れ
Dim arr() As String
arr(0) = "test" '→ エラー!
→ 事前にサイズを指定
ReDim arr(0)
arr(0) = "test"
2. インデックスの開始番号勘違い
- Option Base 1時に0番目へアクセス、等
3. ループ回数固定による範囲超過
- For i = 0 To 10ではなく、LBound/UBoundで管理
4. セル範囲配列は「1始まり」固定
Dim data As Variant
data = Range("A1:A10").Value
Debug.Print data(1, 1) '◎
5. Split関数は「0始まり」固定
arr = Split(text, ",")
Debug.Print arr(UBound(arr)) '◎
まとめ:
配列の開始番号は処理ごとに違う!必ずLBound/UBoundでループせよ
この習慣がバグと手戻りを減らします。
配列 vs Dictionary|どう使い分ける?
| 特徴 | 配列 (Array) | Dictionaryオブジェクト |
|---|---|---|
| アクセス方法 | 数値インデックス | 任意のキー |
| 検索性 | 遅い(ループが必要) | 非常に速い(キー即取得) |
| パフォーマンス | インデックス指定は最速 | わずかにオーバーヘッド |
| 主な用途 | 行列計算、一括処理 | ユニークデータ管理・検索 |
使い分け目安:
- 配列=順次処理・一括計算
- Dictionary=キー付管理・重複排除
用語解説:Dictionaryオブジェクト
VBAで使える連想配列。任意のキー(文字列や数値)で値を管理でき、検索や重複排除に便利。用語解説:インデックス
配列の各要素を識別する番号。0始まり・1始まりなど言語や設定で異なる。用語解説:キー
Dictionaryで値を参照するための識別子。重複不可。
FAQ:よくある疑問・実務Tips
-
Q. VBA配列のインデックスは0始まり?1始まり?
A. デフォルトは0始まり。ただしOption Base 1で1始まりに変更可。
ただしSplitやセル範囲配列は例外なので、必ずLBound/UBoundで確認してください。 -
Q. 配列の中身をデバッグするには?
A. VBEの「ローカルウィンドウ」でブレークポイント後に展開確認が便利です。 -
Q. For EachとFor i = …の使い分けは?
A. 値の変更が必要→For i。読み取り専用ならFor EachでOKです。 -
Q. 配列に格納できる型は?
A. 型宣言で制限可。Variant配列なら何でも入ります。セル範囲一括読込もVariant型。 -
Q. ReDimで多次元配列を拡張できる?
A. 最後の次元のみ可能。最初の次元変更はエラーになるので注意。
ぜひコードをコピペして、まずは動かしてみてください。