ExcelのVBAでデータを大量に扱うとき、セルを一つひとつ読み書きするよりも配列を使った方が処理速度が格段に速くなります。特に表形式のデータを扱う場合に有効なのが2次元配列です。
しかし「1次元配列との違いが分からない」「行と列のインデックスがこんがらがる」「ReDimとPreserveの使い方が曖昧」という悩みを持つ方も多いのではないでしょうか。
本記事では、VBAの2次元配列の基本概念から宣言方法、データの格納・参照・ループ処理、応用テクニック、Excelシートとのデータ連携まで、初心者の方でもすぐに実践できるよう体系的に解説します。
VBAの2次元配列とは

1次元配列との違い
1次元配列は一列に並んだデータの集合です。要素へのアクセスには1つのインデックスだけを使います。
' 1次元配列の例
Dim arr1D(1 To 5) As Integer
arr1D(1) = 10 ' 1つのインデックスで指定
2次元配列は行と列の2つの軸を持つ、表形式のデータ構造です。要素へのアクセスには行インデックスと列インデックスの2つを使います。
' 2次元配列の例
Dim arr2D(1 To 5, 1 To 3) As Integer
arr2D(2, 1) = 10 ' 行2・列1の要素を指定
行と列で構成される配列の仕組み
行列の概念
2次元配列は数学の行列と同じ概念です。第1インデックスが行(縦方向)、第2インデックスが列(横方向)を表します。
' arr(行, 列) の構造
' arr(1,1) arr(1,2) arr(1,3) ← 1行目
' arr(2,1) arr(2,2) arr(2,3) ← 2行目
' arr(3,1) arr(3,2) arr(3,3) ← 3行目
Excelシートとの関係
Excelのシートは行と列で構成されており、2次元配列と完全に対応しています。この性質を利用して、シートのセル範囲を一括で2次元配列に読み込んだり、配列の内容をシートに一括書き出したりすることで、高速なデータ処理が実現できます。
| Excelシート | 2次元配列 |
|---|---|
| 行番号 | 第1インデックス(arr(行, …)) |
| 列番号 | 第2インデックス(arr(…, 列)) |
| セルA1 | arr(1, 1) |
| セルB3 | arr(3, 2) |
2次元配列の宣言方法

固定サイズ配列の宣言
Dim arr(1 To 5, 1 To 3) As Integer
要素数が事前に分かっている場合は固定サイズで宣言します。
' 5行3列の整数型2次元配列を宣言
Dim arr(1 To 5, 1 To 3) As Integer
' 0始まりでも宣言可能(Dim arr(4, 2)は0〜4行・0〜2列) Dim arr2(4, 2) As Integer
' 型を指定しない場合はVariant型になる Dim arrV(1 To 5, 1 To 3)
インデックスの始まりはモジュール先頭に「Option Base 1」を記述することで1に変更できます。記述しない場合のデフォルトは0始まりです。実務では1始まりの明示的な宣言(1 To n)が混乱を避けやすくなります。
可変サイズ配列の宣言と再定義
ReDimの使い方
要素数が実行時に決まる場合は動的配列を使います。まず空の配列を宣言してから、ReDimでサイズを指定します。
' 動的2次元配列の宣言と定義
Dim arr() As Integer ' サイズ未定の動的配列
' 後からサイズを定義 Dim rowCount As Integer Dim colCount As Integer rowCount = 10 colCount = 5
ReDim arr(1 To rowCount, 1 To colCount)
Preserveで既存データを保持
ReDimを実行すると配列の内容がリセットされます。既存のデータを保持したままサイズを変更するにはPreserveキーワードを使います。
Dim arr() As Integer
ReDim arr(1 To 3, 1 To 3)
arr(1, 1) = 10
arr(2, 2) = 20
' Preserveで既存データを保持したままサイズ変更 ' ※2次元配列のPreserveは最後の次元のサイズのみ変更可能 ReDim Preserve arr(1 To 3, 1 To 5)
MsgBox arr(1, 1) ' 10(データが保持されている)
注意:2次元配列でPreserveを使う場合、変更できるのは最後の次元(列方向)のサイズだけです。行方向のサイズを変更するとエラーになります。行方向の動的拡張が必要な場合は、配列の転置や設計の見直しを検討してください。
2次元配列へのデータ格納

値の代入方法
行・列インデックスの指定
Dim arr(1 To 3, 1 To 3) As Integer
' 個別に代入 arr(1, 1) = 10 arr(1, 2) = 20 arr(1, 3) = 30 arr(2, 1) = 40 arr(2, 2) = 50 arr(2, 3) = 60
Forループを使った一括代入
Dim arr(1 To 5, 1 To 3) As Integer
Dim i As Integer, j As Integer
For i = 1 To 5 ' 行のループ For j = 1 To 3 ' 列のループ arr(i, j) = i * 10 + j ' 行と列から値を算出して代入 Next j Next i
' 確認:arr(2,3) = 23 (2×10 + 3)
Excelシートから配列への読み込み
Range.Valueで一括取得
セル範囲の値を一度に2次元配列として取得できます。この方法はセルを1つずつ読み込むよりも処理速度が格段に速く、実務での大量データ処理に欠かせないテクニックです。
Dim arr As Variant
' A1:C5の範囲を一括で配列に読み込む arr = Range("A1:C5").Value
' これだけで5行3列の2次元配列が作成される ' arr(1,1) = A1セルの値 ' arr(1,2) = B1セルの値 ' arr(2,1) = A2セルの値
MsgBox arr(2, 3) ' B列3行目(C2セル)の値を取得
セル範囲の行列対応
Range.Valueで取得した配列は常に1始まりのインデックスになります。行が1〜、列が1〜の形式で対応しています。
' 動的にデータ範囲を取得する実践的な例
Dim lastRow As Long
Dim lastCol As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column
Dim arr As Variant arr = Range(Cells(1, 1), Cells(lastRow, lastCol)).Value
MsgBox "行数: " & UBound(arr, 1) & ", 列数: " & UBound(arr, 2)
VBAの配列操作の詳しい解説については、Microsoft公式ドキュメント「配列の使い方」も参照してください。
2次元配列の参照と操作
個別要素の取得と変更
Dim arr As Variant
arr = Range("A1:D10").Value
' 個別要素の取得 Dim cellValue As Variant cellValue = arr(3, 2) ' 3行2列目の値
' 個別要素の変更 arr(3, 2) = "変更後の値"
' 要素の存在確認(インデックス範囲チェック) If 3 >= LBound(arr, 1) And 3 <= UBound(arr, 1) Then MsgBox arr(3, 1) End If
全体をループして処理する方法
For i = 1 To 行数, For j = 1 To 列数の二重ループ
Dim arr As Variant
arr = Range("A1:C5").Value
Dim i As Long, j As Long
For i = 1 To UBound(arr, 1) ' UBound(arr,1)で行数を取得 For j = 1 To UBound(arr, 2) ' UBound(arr,2)で列数を取得 ' 各要素を処理 Debug.Print "arr(" & i & "," & j & ") = " & arr(i, j) Next j Next i
配列の値を条件付きで操作
Dim arr As Variant
arr = Range("A1:C10").Value
Dim i As Long
For i = 1 To UBound(arr, 1) ' B列(2列目)の値が空でない場合のみ処理 If arr(i, 2) <> "" Then ' A列の値に応じてC列の値を変更 If arr(i, 1) = "特別" Then arr(i, 3) = arr(i, 2) * 1.2 ' 20%増 Else arr(i, 3) = arr(i, 2) End If End If Next i
2次元配列の応用テクニック
並べ替えやフィルタ処理への活用
配列内のデータをバブルソートなどのアルゴリズムで並べ替える実装例です。
Sub SortArrayByColumn(arr As Variant, sortCol As Integer)
Dim i As Long, j As Long
Dim tempRow() As Variant
Dim rowCount As Long
Dim colCount As Long
rowCount = UBound(arr, 1)
colCount = UBound(arr, 2)
ReDim tempRow(1 To colCount)
' バブルソート(指定列で昇順)
For i = 1 To rowCount - 1
For j = 1 To rowCount - i
If arr(j, sortCol) > arr(j + 1, sortCol) Then
' 行全体を入れ替える
Dim k As Long
For k = 1 To colCount
tempRow(k) = arr(j, k)
arr(j, k) = arr(j + 1, k)
arr(j + 1, k) = tempRow(k)
Next k
End If
Next j
Next iEnd Sub
複数配列の結合や分割
' 2つの2次元配列を縦方向に結合する関数
Function CombineArraysVertical(arr1 As Variant, arr2 As Variant) As Variant
Dim rows1 As Long, rows2 As Long, cols As Long
rows1 = UBound(arr1, 1)
rows2 = UBound(arr2, 1)
cols = UBound(arr1, 2) ' 同じ列数を前提
Dim result() As Variant
ReDim result(1 To rows1 + rows2, 1 To cols)
Dim i As Long, j As Long
' arr1をresultにコピー
For i = 1 To rows1
For j = 1 To cols
result(i, j) = arr1(i, j)
Next j
Next i
' arr2をresultにコピー
For i = 1 To rows2
For j = 1 To cols
result(rows1 + i, j) = arr2(i, j)
Next j
Next i
CombineArraysVertical = resultEnd Function
関数やサブルーチンでの引数利用
配列を引数として渡す
' 配列を引数として受け取るSubプロシージャ
Sub ProcessArray(arr As Variant)
Dim i As Long, j As Long
For i = 1 To UBound(arr, 1)
For j = 1 To UBound(arr, 2)
If IsNumeric(arr(i, j)) Then
arr(i, j) = arr(i, j) * 2 ' 数値を2倍にする
End If
Next j
Next i
End Sub
' 呼び出し側 Sub CallExample() Dim data As Variant data = Range("A1:C5").Value ProcessArray data Range("A1:C5").Value = data End Sub
戻り値として2次元配列を返す
' 2次元配列を戻り値として返す関数
Function GetFilteredData(arr As Variant, filterCol As Integer, filterValue As String) As Variant
Dim result() As Variant
Dim resultRow As Long
resultRow = 0
Dim i As Long
For i = 1 To UBound(arr, 1)
If CStr(arr(i, filterCol)) = filterValue Then
resultRow = resultRow + 1
ReDim Preserve result(1 To UBound(arr, 2), 1 To resultRow)
Dim j As Long
For j = 1 To UBound(arr, 2)
result(j, resultRow) = arr(i, j)
Next j
End If
Next i
GetFilteredData = resultEnd Function
注意点とコツ
行列のインデックス範囲を意識
配列のインデックス範囲を確認するにはLBoundとUBound関数を使います。ハードコードされた範囲値を使うよりも、これらの関数を使うことで配列サイズが変わっても対応できる汎用的なコードになります。
Dim arr As Variant
arr = Range("A1:C5").Value
MsgBox "行:" & LBound(arr, 1) & "〜" & UBound(arr, 1) MsgBox "列:" & LBound(arr, 2) & "〜" & UBound(arr, 2)
ReDim時のデータ保持の注意
ReDimを単独で実行すると配列の全内容がリセットされます。データを保持したい場合はPreserveを必ず付けます。ただし2次元配列では最後の次元のみサイズ変更が可能という制約を忘れないようにしましょう。
Excelシートと配列の対応関係を理解
Range.Valueで取得した配列はVariant型になり、インデックスは常に1始まりです。セル範囲の行がそのまま第1インデックス、列が第2インデックスに対応します。この対応関係を正確に理解することが、シートと配列の双方向のデータ連携を確実に実装するための基礎です。
実践例
Excelシートのデータを配列に読み込み処理する例
Sub ReadAndProcessData()
' A1から始まるデータ範囲を動的に取得
Dim ws As Worksheet
Set ws = ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' データを2次元配列に一括読み込み(1行目はヘッダーのため2行目から)
Dim arr As Variant
arr = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 4)).Value
' 配列内で処理:D列(4列目)にA列とB列の合計を計算
Dim i As Long
For i = 1 To UBound(arr, 1)
If IsNumeric(arr(i, 1)) And IsNumeric(arr(i, 2)) Then
arr(i, 4) = arr(i, 1) + arr(i, 2)
End If
Next i
' 処理結果をシートに書き戻す
ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, 4)).Value = arr
MsgBox "処理が完了しました。" & UBound(arr, 1) & "行を処理しました。"End Sub
条件に応じた配列内データの更新例
Sub UpdateDataByCondition()
Dim ws As Worksheet
Set ws = ActiveSheet
Dim arr As Variant
arr = ws.Range("A1:E" & ws.Cells(ws.Rows.Count, 1).End(xlUp).Row).Value
Dim i As Long
For i = 2 To UBound(arr, 1) ' 1行目はヘッダーのためスキップ
' C列(3列目)が"対象"の場合、E列(5列目)に"処理済み"をセット
If arr(i, 3) = "対象" Then
arr(i, 5) = "処理済み"
ElseIf arr(i, 3) = "除外" Then
arr(i, 5) = "スキップ"
Else
arr(i, 5) = "未定義"
End If
Next i
ws.Range("A1:E" & UBound(arr, 1)).Value = arrEnd Sub
配列をExcelに書き戻す例
Sub WriteArrayToSheet()
' 新しいシートに書き出す例
Dim srcSheet As Worksheet
Dim dstSheet As Worksheet
Set srcSheet = Sheets("データ元")
Set dstSheet = Sheets("出力先")
' 元データを配列に読み込む
Dim arr As Variant
arr = srcSheet.Range("A1:D100").Value
' 配列内でデータを加工
Dim i As Long
For i = 1 To UBound(arr, 1)
If arr(i, 4) = "" Then
arr(i, 4) = "未入力" ' 空欄を"未入力"に変換
End If
Next i
' 出力先シートに一括書き出し
dstSheet.Cells.ClearContents ' 既存データをクリア
dstSheet.Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)).Value = arr
MsgBox "書き出し完了:" & UBound(arr, 1) & "行 × " & UBound(arr, 2) & "列"End Sub
VBAの2次元配列の詳しい使い方については、侍エンジニア「VBAの2次元配列の使い方まとめ」、ExcelVBA解説「2次元配列の操作と応用」、残業なし「VBAの2次元配列を徹底解説」も参考にしてください。
VBAをはじめとするExcel活用術や業務効率化のヒントは、kakiro-web.comでも幅広く解説しています。
まとめ
VBAの2次元配列は行列構造を理解して操作することが基本
2次元配列はExcelの行と列に対応した表形式のデータ構造です。第1インデックスが行、第2インデックスが列という基本的な対応関係を正確に理解することが、すべての操作の土台になります。
データの格納・参照・ループ処理を組み合わせて効率的に活用
Range.Valueによるシートからの一括読み込み、二重ループによる全要素の処理、処理後の一括書き戻しという一連のパターンを使いこなすことで、セルを1つずつ操作するよりも処理速度が大幅に向上します。
応用テクニックでExcelデータの自動化や高度な処理を実現
並べ替え・フィルタ・配列の結合・関数への引数渡しなどの応用テクニックと組み合わせることで、複雑なデータ処理を効率的に自動化できます。
- 固定サイズ配列は
Dim arr(1 To 行, 1 To 列)で宣言する - 動的配列は
Dim arr()→ReDim arr(1 To 行, 1 To 列)で使う - データを保持したままサイズ変更するには
ReDim Preserveを使う(最後の次元のみ変更可能) - Range.Valueで一括読み込みするとセル操作より処理速度が大幅に速い
UBound(arr, 1)で行数、UBound(arr, 2)で列数を取得できる- 二重ループで全要素を処理するのが2次元配列の基本パターン
- 処理後は
Range.Value = arrで一括書き戻しができる

