VBAで2次元配列を扱うとき、UBound でまず覚えるのは、UBound(arr, 1) が1つ目の次元、UBound(arr, 2) が2つ目の次元を見るということです。
2次元配列をExcelの表として扱うなら、基本は arr(行, 列) と考えます。ただし配列の開始番号は0とは限らないため、正確な行数・列数は UBound(arr, 次元) - LBound(arr, 次元) + 1 で取得します。
セル範囲を Range.Value で読み込むと、複数セルの場合は値を2次元配列として扱えます。加工後は Range("E1").Resize(行数, 列数).Value = arr の形でまとめて貼り付けます。
ReDim Preserve は最後の次元しかサイズ変更できません。arr(行, 列) のまま行を増やしたい場合は、先に必要な行数を数えてから ReDim するのが安全です。
VBAの2次元配列は、最初に見るとかなり難しく感じます。
理由は、同時に考えることが多いからです。Dim、ReDim、UBound、LBound、Range.Value、Resize が一気に出てきますし、さらに「配列は0から始まるのか、1から始まるのか」という混乱もあります。
この記事では、現行記事で扱っていた2次元配列の基礎、動的宣言、CurrentRegion、セルへの貼り付け、1行ずつ処理する使い方、ReDim Preserveの注意点を残したまま、UBoundで2次元配列の行数・列数を確認する方法を軸に整理し直します。
初心者の方は、先に「UBoundで2次元配列の行数と列数を取る」ところだけ押さえてください。そこが分かると、動的配列、貼り付け、1行ずつの処理まで一気につながります。
また、実際に手を動かす場面では「2次元の動的配列をどう宣言するか」「配列をセルへ貼り付けるにはどうするか」「ReDim Preserveで行数を増やせないのはなぜか」まで一緒に理解する必要があります。この記事では、それらを別々の断片ではなく、2次元配列を使う一連の流れとして扱います。
【 この記事の概要 】
| よく使う度 | |
| 難しさ | |
| 覚えておくと安心度 |
| 知りたいこと | 読む場所 |
|---|---|
UBound(arr, 1) と UBound(arr, 2) の違い | UBoundの次元指定を見る |
| 2次元配列の行数・列数を安全に取得したい | 行数・列数の計算を見る |
| 動的な2次元配列を宣言したい | 動的配列の宣言を見る |
| 2次元配列の考え方を初心者向けに知りたい | 2次元配列の考え方を見る |
| セル範囲を配列に入れて、別のセルへ貼り付けたい | セルへの貼り付けを見る |
| 2次元配列を1行ずつ処理したい | 1行ずつ処理する例を見る |
ReDim Preserve でエラーになる理由を知りたい | ReDim Preserveの制限を見る |
VBAのUBoundで2次元配列の行数・列数を取得する基本
2次元配列を実務で使うとき、最初に必要になるのは「この配列は何行・何列あるのか」を知ることです。
セル範囲を配列に入れたあと、行数や列数が分からないまま処理を書くと、最後の行を読み飛ばしたり、貼り付け先のセル範囲がずれたりします。
ここでは、2次元配列でUBoundをどう使うか知りたい方に向けて、UBound と LBound の使い方から確認します。
UBound(arr, 1)とUBound(arr, 2)の違い
UBound は、配列の上限番号を返す関数です。
2次元配列の場合は、2つ目の引数に「どの次元を見るか」を指定します。
Sub Check2DArraySize()
Dim arr As Variant
arr = Worksheets("Sheet1").Range("A1:C4").Value
Debug.Print "行の下限: " & LBound(arr, 1)
Debug.Print "行の上限: " & UBound(arr, 1)
Debug.Print "列の下限: " & LBound(arr, 2)
Debug.Print "列の上限: " & UBound(arr, 2)
End SubExcelの表として考えるなら、基本は次のように読みます。
| 書き方 | 見ているもの | Excel表のイメージ |
|---|---|---|
UBound(arr, 1) | 1つ目の次元の上限 | 行方向 |
UBound(arr, 2) | 2つ目の次元の上限 | 列方向 |
LBound(arr, 1) | 1つ目の次元の下限 | 最初の行番号 |
LBound(arr, 2) | 2つ目の次元の下限 | 最初の列番号 |
Microsoft LearnのUBound関数でも、UBound(arrayname, [dimension]) の dimension は、1なら第1次元、2なら第2次元を返すものとして説明されています。
つまり、2次元配列で「行数を見たい」のに UBound(arr) だけで書くと、意図が伝わりにくくなります。省略すると第1次元が対象になりますが、2次元配列では UBound(arr, 1) と明示した方が読みやすいです。

UBoundとLBoundそのものを先に整理したい場合は、関連記事の LBound、UBound (配列のサイズを知る) もあわせて確認すると理解しやすいです。
行数・列数を変数に入れて使い回す
実務では、上限番号そのものよりも「何行あるか」「何列あるか」を使う場面が多いです。
そのため、上限だけを見るのではなく、下限を返す Microsoft LearnのLBound関数 も含めて行数・列数を計算しておくと安全です。
Sub GetRowAndColumnCount()
Dim arr As Variant
Dim rowCount As Long
Dim colCount As Long
arr = Worksheets("Sheet1").Range("A1:C4").Value
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
colCount = UBound(arr, 2) - LBound(arr, 2) + 1
Debug.Print "行数: " & rowCount
Debug.Print "列数: " & colCount
End SubRange.Value で取得した複数セルの配列は、実務上は 1 To 行数, 1 To 列数 の感覚で扱う場面が多いです。ただし、すべての配列が1始まりとは限りません。
たとえば、Dim arr(0 To 2, 0 To 3) のように自分で宣言した配列なら0始まりです。Option Baseステートメント を使っているモジュールもあります。だからこそ、初心者のうちから UBound - LBound + 1 で行数・列数を出す癖をつけると、後で詰まりにくくなります。
動的な2次元配列を宣言して必要サイズだけ確保する
2次元配列の宣言には、最初からサイズを決める方法と、あとからサイズを決める方法があります。
最初からサイズを決める配列を、ここでは固定サイズの配列として扱います。
Sub Static2DArraySample()
Dim data(1 To 4, 1 To 3) As Variant
data(1, 1) = "名前"
data(1, 2) = "点数"
data(1, 3) = "判定"
End Sub行数や列数が処理のたびに変わるなら、動的配列にします。
Sub Dynamic2DArraySample()
Dim rowCount As Long
Dim colCount As Long
Dim data() As Variant
rowCount = 4
colCount = 3
ReDim data(1 To rowCount, 1 To colCount)
data(1, 1) = "名前"
data(1, 2) = "点数"
data(1, 3) = "判定"
End SubMicrosoft LearnのDimステートメントでも、空の括弧で動的配列を宣言し、あとから ReDim で要素数を定義できるとされています。
配列の宣言、固定サイズの配列、動的配列の全体像を先に押さえたい場合は、関連記事の VBA 配列の使い方徹底解説 を先に読むと、このあとのコードが追いやすくなります。
初心者の方は、まず次の形をテンプレートとして覚えるのがおすすめです。
Dim arr() As Variant
ReDim arr(1 To rowCount, 1 To colCount)この形にしておくと、UBound(arr, 1) で行方向、UBound(arr, 2) で列方向を見られるため、Excelの表と対応させやすくなります。
2次元配列とは?初心者向けにExcel表で考える
2次元配列は、Excelの表をVBAの中に一時的に持つための入れ物です。
1つの値だけを変数に入れるのではなく、複数行・複数列の値をまとめて扱えます。

1次元配列と2次元配列の違い
1次元配列は、横一列または縦一列のリストとして考えると分かりやすいです。
Dim names(1 To 3) As String
names(1) = "佐藤"
names(2) = "田中"
names(3) = "鈴木"一方、2次元配列は「行」と「列」の2つの番号で値を指定します。
Dim data(1 To 3, 1 To 2) As Variant
data(1, 1) = "佐藤"
data(1, 2) = 85
data(2, 1) = "田中"
data(2, 2) = 58
data(3, 1) = "鈴木"
data(3, 2) = 72data(2, 1) は2行目・1列目です。Excelのセル番地でいう A2 と似た感覚ですが、完全に同じではありません。
配列の中では、あくまで「配列内の何行目・何列目か」を見ています。ここをExcelのセル番地と混同すると、arr(2, 3) が B3 なのか C2 なのか分からなくなります。
この記事では、初心者向けに arr(行, 列) の順番で統一して説明します。
Range.Valueでセル範囲を2次元配列に入れる
Excel VBAで2次元配列がよく使われる理由は、セル範囲と相性がよいからです。
Microsoft LearnのRange.Valueプロパティでは、複数セル範囲の値は2次元配列を含む Variant として返されると説明されています。また、2次元配列を Value に代入すると、範囲へ一括でコピーできます。
Sub GetArrayFromRange()
Dim arr As Variant
arr = Range("A1").CurrentRegion.Value
End Sub
範囲が毎回変わるなら、CurrentRegion を使う方法もあります。CurrentRegionの基本を別記事で確認したい場合は、VBA CurrentRegionでセル範囲を自動取得・最終行やセル操作を解説 も参考になります。
Sub ReadCurrentRegionAsArray()
Dim arr As Variant
Dim targetRange As Range
Set targetRange = Worksheets("Sheet1").Range("A1").CurrentRegion
arr = targetRange.Value
Debug.Print "行数: " & UBound(arr, 1) - LBound(arr, 1) + 1
Debug.Print "列数: " & UBound(arr, 2) - LBound(arr, 2) + 1
End SubMicrosoft LearnのRange.CurrentRegionプロパティでは、CurrentRegion は空白行や空白列で囲まれた範囲を返すものとして説明されています。表の途中に空白行・空白列があると、想定より狭い範囲になることがあります。また、保護されたワークシートでは使えない点も公式ドキュメントに明記されています。

添字は0始まり・1始まりが混ざるのでLBoundも見る
VBAの配列で初心者が混乱しやすいのが、開始番号です。
たとえば、次の配列は0始まりです。
Dim arr(0 To 2, 0 To 3) As Variant次の配列は1始まりです。
Dim arr(1 To 3, 1 To 4) As Variantさらに、Option Base 1 が書かれたモジュールでは、下限を明示しない配列の開始番号が変わります。
そのため、2次元配列を安全に扱うなら、UBound だけでなく LBound も見ます。
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
colCount = UBound(arr, 2) - LBound(arr, 2) + 1この書き方なら、0始まりでも1始まりでも行数・列数を正しく取得できます。
2次元配列を貼り付ける・1行ずつ処理する・ReDim Preserveで増やす
ここからは、現行記事でも扱っていた実務寄りの使い方を、UBound を中心に整理します。
2次元配列は「読み込む」だけではあまり価値がありません。実務では、読み込んだ値を加工し、必要な形で貼り付けるところまで使います。

2次元配列をセルにまとめて貼り付ける
配列をセルへ貼り付けるときは、貼り付け先の範囲サイズを配列サイズに合わせます。
Sub Paste2DArrayToSheet()
Dim arr(1 To 4, 1 To 3) As Variant
Dim rowCount As Long
Dim colCount As Long
arr(1, 1) = "名前"
arr(1, 2) = "点数"
arr(1, 3) = "判定"
arr(2, 1) = "佐藤"
arr(2, 2) = 85
arr(2, 3) = "合格"
arr(3, 1) = "田中"
arr(3, 2) = 58
arr(3, 3) = "確認"
arr(4, 1) = "鈴木"
arr(4, 2) = 72
arr(4, 3) = "合格"
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
colCount = UBound(arr, 2) - LBound(arr, 2) + 1
Worksheets("Sheet1").Range("B1").Resize(rowCount, colCount).Value = arr
End Sub
ポイントは、Resize(rowCount, colCount) です。
貼り付け先が小さいと、配列の一部しか貼り付けられません。貼り付け先が大きすぎると、余ったセルにエラー値が入ることがあります。Range.Valueの公式説明でも、対象範囲が配列より大きい場合、残りのセルにエラー値が入るとされています。
そのため、配列を貼り付けるときは、先に UBound と LBound で行数・列数を出してから Resize します。
Range や Cells の指定がまだあいまいな場合は VBA RangeとCellsの使い方 を、Resize の考え方を深掘りしたい場合は VBA Resizeの使い方 を先に確認すると、貼り付け先の範囲指定で迷いにくくなります。
2次元配列を1行ずつ処理する
次は、セル範囲を配列に入れて、1行ずつ判定してから別の場所に貼り付ける例です。
例として、点数が70点以上なら「合格」、70点未満なら「確認」と入れます。
Sub JudgeScoresBy2DArray()
Dim ws As Worksheet
Dim arr As Variant
Dim i As Long
Dim rowCount As Long
Dim colCount As Long
Set ws = Worksheets("Sheet1")
arr = ws.Range("A1").CurrentRegion.Value
For i = LBound(arr, 1) + 1 To UBound(arr, 1)
If Val(arr(i, 2)) >= 70 Then
arr(i, 3) = "合格"
Else
arr(i, 3) = "確認"
End If
Next i
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
colCount = UBound(arr, 2) - LBound(arr, 2) + 1
ws.Range("E1").Resize(rowCount, colCount).Value = arr
End Sub
For i = LBound(arr, 1) + 1 To UBound(arr, 1) としているのは、1行目を見出し行として扱っているためです。
For 文の基本構文に不安がある場合は、関連記事の VBA For文の使い方 で先に流れを確認しておくと、この処理の意味が追いやすくなります。
もし見出し行がない表なら、LBound(arr, 1) から開始します。
For i = LBound(arr, 1) To UBound(arr, 1)
' 見出し行がない場合の処理
Next i2次元配列を1行ずつ処理するときは、次の3点をセットで見ると安全です。
| 確認すること | 例 |
|---|---|
| 何行目から処理するか | 見出しありなら LBound(arr, 1) + 1 |
| 何列目を判定に使うか | 点数列なら arr(i, 2) |
| どの列へ結果を書くか | 判定列なら arr(i, 3) |
セルを1つずつ読み書きするコードでも同じ処理はできます。ただ、行数が増えるほど処理が遅くなりやすく、コードも散らばります。
配列に入れてから処理し、最後にまとめて貼り付ける形にすると、処理の流れが「読み込み → 加工 → 出力」に分かれるため、あとから見返しやすくなります。
ReDim Preserveは最後の次元だけ
2次元配列でよくあるつまずきが、ReDim Preserve です。
ReDim Preserve は、配列の中身を残したままサイズを変更したいときに使います。ただし、Microsoft LearnのReDimステートメントでは、Preserve を使う場合は最後の次元だけを変更できると説明されています。

たとえば、次のコードは「列方向」を増やしているため考え方としては問題ありません。
Sub PreserveColumnSample()
Dim arr() As Variant
ReDim arr(1 To 3, 1 To 3)
arr(1, 1) = "A"
ReDim Preserve arr(1 To 3, 1 To 5)
End Sub一方、次のように「行方向」を増やそうとすると、Preserve の制限に引っかかります。
Sub PreserveRowErrorSample()
Dim arr() As Variant
ReDim arr(1 To 3, 1 To 3)
arr(1, 1) = "A"
ReDim Preserve arr(1 To 5, 1 To 3)
End Sub
実務では、次の順番にすると安全です。
- 先に対象行数を数える
- 必要なサイズで
ReDimする - 配列へ値を入れる
- 最後にセルへまとめて貼り付ける
次の例では、点数が70点以上の行だけを抽出して別の場所へ貼り付けます。
Sub ExtractPassedRows()
Dim ws As Worksheet
Dim source As Variant
Dim result() As Variant
Dim i As Long
Dim j As Long
Dim outRow As Long
Dim passCount As Long
Dim colCount As Long
Set ws = Worksheets("Sheet1")
source = ws.Range("A1").CurrentRegion.Value
colCount = UBound(source, 2) - LBound(source, 2) + 1
For i = LBound(source, 1) + 1 To UBound(source, 1)
If Val(source(i, 2)) >= 70 Then
passCount = passCount + 1
End If
Next i
If passCount = 0 Then
MsgBox "抽出対象がありません。"
Exit Sub
End If
ReDim result(1 To passCount + 1, 1 To colCount)
For j = 1 To colCount
result(1, j) = source(LBound(source, 1), LBound(source, 2) + j - 1)
Next j
outRow = 1
For i = LBound(source, 1) + 1 To UBound(source, 1)
If Val(source(i, 2)) >= 70 Then
outRow = outRow + 1
For j = 1 To colCount
result(outRow, j) = source(i, LBound(source, 2) + j - 1)
Next j
End If
Next i
ws.Range("E1").Resize(UBound(result, 1), UBound(result, 2)).Value = result
End Sub
このコードは少し長く見えますが、やっていることは単純です。
最初に対象行数を数え、必要な分だけ result を確保し、そのあとで値を入れています。ReDim Preserve で行を増やし続けるより、初心者にとってもエラーの原因を追いやすいです。
2次元配列だけでなく、Range・UBound・動的配列まで理解したい方は、VBA講座も確認しておくと迷いにくいです
この記事のコードだけでも、arr(行, 列)、UBound(arr, 1)、UBound(arr, 2) は試せます。ただ、実務では Range で読み込み、ReDim でサイズを変え、Excelへまとめて貼り付ける流れまでつながります。画面を見ながら学びたい場合は、動画講座も候補になります。
※価格・割引・返金条件・講座内容は変わる場合があります。購入前にUdemy上で最新情報をご確認ください。
よくある質問とまとめ:UBoundから2次元配列を理解する
最後に、2次元配列とUBoundでつまずきやすい点をFAQ形式で整理します。
よくある質問
まとめ
2次元配列は、最初は難しく見えます。
ただ、軸を UBound に置くと理解しやすくなります。
UBound(arr, 1)は第1次元、Excel表のイメージでは行方向UBound(arr, 2)は第2次元、Excel表のイメージでは列方向- 正確な行数・列数は
UBound - LBound + 1で取得する - 複数セルの
Range.Valueは2次元配列として扱える - セルへ戻すときは
Resize(行数, 列数).Value = arr ReDim Preserveは最後の次元だけサイズ変更できる- 行方向に増やしたいなら、先に必要行数を数えてから
ReDimする
初心者の方は、いきなり複雑な抽出処理を書くよりも、まず次の3つを手元で動かすのがおすすめです。
Range.Valueでセル範囲を配列に入れるUBound(arr, 1)とUBound(arr, 2)をDebug.Printで確認するResize(rowCount, colCount).Value = arrで別の場所に貼り付ける
この3つがつながると、2次元配列は「難しい概念」ではなく、「Excelの表を一時的にVBAの中へ持つ方法」として使えるようになります。
配列で一覧を作れるようになったら、次は「会議メモをExcelへ戻せる形」で整理しませんか?
TsunaGraphは、箇条書きからマインドマップを作り、JSON・CSV・PNGで保存できるローカルアプリです。会議の論点やタスクを1枚で整理し、CSVでExcelへ戻せるので、WBSや進捗表の下書きにもつなげやすくなります。
※TsunaGraphは筆者が作成した自社製品です。無料Lite版、Standard版の違い、動作環境、価格はリンク先で確認できます。
TsunaGraphの実画面
TsunaGraphを確認する前に見るポイント
- 向いている人: 会議メモ、タスク一覧、論点整理をExcelへ戻す機会が多い人。
- できること: 箇条書きからマインドマップ化し、JSON・CSV・PNGで保存できます。
- Standard版: Excel補助ブックつき。CSVをWBSや進捗表の下書きに戻しやすくなります。
- 向いていない人: リアルタイム共同編集、クラウド同期、スマホ中心の作図が必須の人。
- 無料の代替: Excelのアウトライン、表、図形でも整理できます。ただし後から構造を直す手間は増えやすいです。

