ExcelのVBAで配列を扱っていると、「この配列に何個の要素が入っているか」を確認したい場面が頻繁に出てきます。ループ処理の終了条件を設定するとき、配列が空かどうかをチェックするとき、動的配列にReDimで再定義した後に要素数を確認するときなど、配列の要素数取得はVBA開発の基本スキルのひとつです。
しかし「UBoundとLBoundの違いが分からない」「多次元配列の行数と列数をどう取得するか迷う」「配列が空かどうかをどうチェックするか分からない」という悩みを持つ方も多いのではないでしょうか。
本記事では、UBound・LBound関数の基本から要素数の計算方法、多次元配列での応用、動的配列との組み合わせ、実践的なコード例まで、初心者の方でもすぐに活用できるよう体系的に解説します。
VBAの配列とは

配列の基本概念
配列とは、同じデータ型の複数の値を一つの変数名でまとめて管理するデータ構造です。個々の値(要素)にはインデックス(添字)と呼ばれる番号でアクセスします。
' 個別変数で管理する場合(非効率)
Dim name1 As String
Dim name2 As String
Dim name3 As String
' 配列で管理する場合(効率的) Dim names(1 To 3) As String names(1) = "田中" names(2) = "山田" names(3) = "佐藤"
配列を使うことで、ループ処理による一括操作・可変長データの管理・高速なデータ処理が可能になります。
1次元配列と多次元配列の違い
行列構造の理解
1次元配列はひとつのインデックスで要素を指定する一列構造です。多次元配列は複数のインデックスで要素を指定する表構造で、2次元配列は行と列の2つの軸を持ちます。
' 1次元配列(5つの要素)
Dim arr1D(1 To 5) As Integer
' 2次元配列(3行×4列) Dim arr2D(1 To 3, 1 To 4) As Integer
' 3次元配列(3×4×2) Dim arr3D(1 To 3, 1 To 4, 1 To 2) As Integer
Excelシートとの連携
ExcelのセルはRange.Valueで一括して2次元配列に読み込めます。読み込んだ配列の第1インデックスが行、第2インデックスが列に対応します。この特性を活かして、UBoundで行数・列数を取得することで汎用的なシートデータ処理が実現できます。
配列の要素数を取得する基本方法

UBound関数の使い方
配列の最大インデックスを取得
UBound(Upper Bound)は配列の最大インデックス値を返す関数です。
UBound(配列名 [, 次元番号])
次元番号は省略すると1(第1次元)が適用されます。
1次元配列の例
Dim fruits(1 To 5) As String
fruits(1) = "りんご"
fruits(2) = "バナナ"
fruits(3) = "みかん"
fruits(4) = "ぶどう"
fruits(5) = "いちご"
Dim maxIndex As Integer maxIndex = UBound(fruits)
MsgBox "最大インデックス: " & maxIndex ' 出力:5
0始まりの配列の場合:
Dim nums(0 To 4) As Integer ' インデックス0〜4の5要素
MsgBox UBound(nums) ' 出力:4(最大インデックスは4)
LBound関数の使い方
配列の最小インデックスを取得
LBound(Lower Bound)は配列の最小インデックス値を返す関数です。
LBound(配列名 [, 次元番号])
要素数計算に応用
Dim arr(3 To 8) As Integer ' インデックス3〜8の配列
MsgBox "最小インデックス: " & LBound(arr) ' 出力:3 MsgBox "最大インデックス: " & UBound(arr) ' 出力:8
LBoundが重要なのは、配列のインデックスが0始まりか1始まりかによって要素数の計算が変わるからです。常にLBoundを使うことで、インデックスの開始値にかかわらず正確な要素数が取得できます。
配列の要素数を計算する方法
UBound – LBound + 1 の公式
配列の要素数は以下の公式で正確に計算できます。
要素数 = UBound(配列) - LBound(配列) + 1
' 様々なインデックス範囲での要素数計算
Dim arrA(1 To 5) As Integer ' 1〜5 → 要素数5
Dim arrB(0 To 4) As Integer ' 0〜4 → 要素数5
Dim arrC(3 To 8) As Integer ' 3〜8 → 要素数6
MsgBox UBound(arrA) - LBound(arrA) + 1 ' 5 - 1 + 1 = 5 MsgBox UBound(arrB) - LBound(arrB) + 1 ' 4 - 0 + 1 = 5 MsgBox UBound(arrC) - LBound(arrC) + 1 ' 8 - 3 + 1 = 6
1次元・2次元配列での応用
Sub GetElementCount()
Dim arr1D(1 To 10) As Integer
Dim arr2D(1 To 5, 1 To 3) As Integer
' 1次元配列の要素数
Dim count1D As Integer
count1D = UBound(arr1D) - LBound(arr1D) + 1
MsgBox "1次元配列の要素数: " & count1D ' 10
' 2次元配列の総要素数
Dim rowCount As Integer
Dim colCount As Integer
rowCount = UBound(arr2D, 1) - LBound(arr2D, 1) + 1
colCount = UBound(arr2D, 2) - LBound(arr2D, 2) + 1
MsgBox "行数: " & rowCount & ", 列数: " & colCount & ", 総要素数: " & rowCount * colCountEnd Sub
多次元配列の要素数取得

行数と列数の取得方法
UBound(配列, 次元番号) の活用
多次元配列では次元番号を指定することで、各次元の最大・最小インデックスを個別に取得できます。
Dim arr2D(1 To 4, 1 To 6) As Integer
' 第1次元(行)の情報 MsgBox "行の最小インデックス: " & LBound(arr2D, 1) ' 1 MsgBox "行の最大インデックス: " & UBound(arr2D, 1) ' 4 MsgBox "行数: " & (UBound(arr2D, 1) - LBound(arr2D, 1) + 1) ' 4
' 第2次元(列)の情報 MsgBox "列の最小インデックス: " & LBound(arr2D, 2) ' 1 MsgBox "列の最大インデックス: " & UBound(arr2D, 2) ' 6 MsgBox "列数: " & (UBound(arr2D, 2) - LBound(arr2D, 2) + 1) ' 6
各次元の要素数を取得してループ処理に利用
Sub Process2DArray()
' Excelシートのデータを2次元配列に読み込む
Dim ws As Worksheet
Set ws = ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim arr As Variant
arr = ws.Range("A1:C" & lastRow).Value
' 行数と列数をUBoundで取得
Dim rowCount As Long
Dim colCount As Long
rowCount = UBound(arr, 1) ' Range.Valueは常に1始まり
colCount = UBound(arr, 2)
MsgBox "行数: " & rowCount & ", 列数: " & colCount
' 取得した要素数でループ
Dim i As Long, j As Long
For i = 1 To rowCount
For j = 1 To colCount
' 各セルのデータを処理
Debug.Print "arr(" & i & "," & j & ") = " & arr(i, j)
Next j
Next iEnd Sub
UBound・LBound関数の詳しい解説については、JavaDrive「ExcelVBAのUBound関数とLBound関数の使い方」も参考になります。
配列要素数取得の応用テクニック
配列が空かどうかのチェック
動的配列はReDimを実行する前の状態では「空の配列」であり、UBoundを実行するとエラーになります。配列が空かどうかを事前に確認する方法が重要です。
' 方法1:IsArray関数とOn Errorの組み合わせ
Function IsEmptyArray(arr As Variant) As Boolean
If Not IsArray(arr) Then
IsEmptyArray = True
Exit Function
End If
On Error Resume Next
Dim test As Long
test = UBound(arr)
If Err.Number <> 0 Then
IsEmptyArray = True
Else
IsEmptyArray = False
End If
On Error GoTo 0End Function
' 使用例 Dim dynArr() As Integer ' 空の動的配列
If IsEmptyArray(dynArr) Then MsgBox "配列は空です" Else MsgBox "要素数: " & (UBound(dynArr) - LBound(dynArr) + 1) End If
' 方法2:より簡潔なチェック
Function ArrayHasElements(arr As Variant) As Boolean
On Error Resume Next
Dim n As Long
n = UBound(arr)
ArrayHasElements = (Err.Number = 0)
On Error GoTo 0
End Function
配列のサイズに応じた動的処理
Forループでの安全な反復処理
要素数に応じて処理を分岐させる実践的なパターンです。
Sub SafeArrayProcess(arr As Variant)
' 配列の存在確認
If Not IsArray(arr) Then
MsgBox "配列ではありません"
Exit Sub
End If
' 空配列チェック
Dim elementCount As Long
On Error Resume Next
elementCount = UBound(arr) - LBound(arr) + 1
If Err.Number <> 0 Then
MsgBox "配列が初期化されていません"
Exit Sub
End If
On Error GoTo 0
' 要素数に応じた処理分岐
If elementCount = 0 Then
MsgBox "要素が0件です"
ElseIf elementCount <= 10 Then
MsgBox "少量データ(" & elementCount & "件):個別処理モード"
Else
MsgBox "大量データ(" & elementCount & "件):一括処理モード"
End IfEnd Sub
動的配列の再定義と要素数確認
Sub DynamicArrayExample()
Dim arr() As String
Dim inputCount As Integer
inputCount = 5 ' 実際はユーザー入力や処理結果から取得
' ReDimで要素数を定義
ReDim arr(1 To inputCount)
' データを格納
Dim i As Integer
For i = 1 To inputCount
arr(i) = "データ" & i
Next i
' 要素数の確認
MsgBox "現在の要素数: " & (UBound(arr) - LBound(arr) + 1)
' 追加データが必要になった場合
Dim addCount As Integer
addCount = 3
ReDim Preserve arr(1 To inputCount + addCount)
' 再定義後の要素数を確認
MsgBox "再定義後の要素数: " & (UBound(arr) - LBound(arr) + 1)End Sub
VBA配列操作の注意点
配列宣言時のインデックス範囲
VBAのデフォルトではインデックスは0始まりですが、モジュールの先頭にOption Base 1を記述すると1始まりになります。
' Option Base 1を記述した場合
Option Base 1
Sub TestOptionBase() Dim arr(5) As Integer ' インデックス1〜5の配列になる MsgBox "LBound: " & LBound(arr) ' 1 MsgBox "UBound: " & UBound(arr) ' 5 MsgBox "要素数: " & (UBound(arr) - LBound(arr) + 1) ' 5 End Sub
Option Baseの設定はモジュール単位で有効です。異なるモジュール間でOption Baseの設定が違うと混乱の原因になります。実務では「1 To n」形式で明示的にインデックス範囲を指定することを推奨します。
動的配列でのReDimと要素数の関係
Preserveでデータ保持
ReDimを単独で実行すると配列の全内容がリセットされます。
Dim arr() As Integer
ReDim arr(1 To 5)
arr(1) = 100
ReDim arr(1 To 10) ' データがリセットされる MsgBox arr(1) ' 0(リセット済み)
' Preserveを使うとデータを保持できる ReDim arr(1 To 5) arr(1) = 100
ReDim Preserve arr(1 To 10) ' データを保持してサイズ変更 MsgBox arr(1) ' 100(保持されている)
再定義後の要素数チェック
Sub ReDimWithCheck()
Dim arr() As Integer
ReDim arr(1 To 5)
' 初期要素数の確認
Debug.Print "初期要素数: " & (UBound(arr) - LBound(arr) + 1) ' 5
' 拡張
ReDim Preserve arr(1 To 10)
Debug.Print "拡張後の要素数: " & (UBound(arr) - LBound(arr) + 1) ' 10
' 縮小(Preserveでも縮小は可能、但し削除された要素のデータは失われる)
ReDim Preserve arr(1 To 7)
Debug.Print "縮小後の要素数: " & (UBound(arr) - LBound(arr) + 1) ' 7End Sub
実践例
配列要素数に応じたループ処理
Sub LoopWithElementCount()
Dim scores(1 To 5) As Integer
scores(1) = 85
scores(2) = 92
scores(3) = 78
scores(4) = 95
scores(5) = 88
' UBoundとLBoundで安全にループ
Dim total As Long
Dim i As Integer
For i = LBound(scores) To UBound(scores)
total = total + scores(i)
Next i
Dim elementCount As Integer
elementCount = UBound(scores) - LBound(scores) + 1
MsgBox "要素数: " & elementCount & Chr(10) & _
"合計: " & total & Chr(10) & _
"平均: " & Format(total / elementCount, "0.0")End Sub
Excelシートのデータを配列に読み込み、要素数で処理分岐
Sub ReadSheetAndProcess()
Dim ws As Worksheet
Set ws = ActiveSheet
' データ範囲を動的に取得
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません"
Exit Sub
End If
' 2行目(ヘッダー除く)からデータを読み込む
Dim arr As Variant
arr = ws.Range("A2:B" & lastRow).Value
' 要素数(行数)を取得
Dim rowCount As Long
rowCount = UBound(arr, 1) - LBound(arr, 1) + 1
MsgBox "読み込んだデータ: " & rowCount & "件"
' 要素数に応じて処理を分岐
Dim i As Long
For i = 1 To rowCount
If IsNumeric(arr(i, 2)) Then
If CLng(arr(i, 2)) >= 80 Then
' 合格処理
ws.Cells(i + 1, 3).Value = "合格"
Else
' 不合格処理
ws.Cells(i + 1, 3).Value = "不合格"
End If
End If
Next i
MsgBox "処理完了:" & rowCount & "件"End Sub
動的配列でユーザー入力に応じて要素数を変更
Sub DynamicArrayWithUserInput()
' ユーザーから入力数を取得
Dim inputStr As String
inputStr = InputBox("登録するデータ数を入力してください:", "データ数入力")
If inputStr = "" Then Exit Sub
If Not IsNumeric(inputStr) Then
MsgBox "数値を入力してください"
Exit Sub
End If
Dim count As Integer
count = CInt(inputStr)
If count <= 0 Then
MsgBox "1以上の数値を入力してください"
Exit Sub
End If
' 入力数に応じて動的配列を定義
Dim dataArr() As String
ReDim dataArr(1 To count)
' データを収集
Dim i As Integer
For i = 1 To count
dataArr(i) = InputBox(i & "件目のデータを入力:", "データ入力")
Next i
' 要素数の確認と結果表示
Dim elementCount As Integer
elementCount = UBound(dataArr) - LBound(dataArr) + 1
Dim result As String
result = "登録データ(" & elementCount & "件):" & Chr(10)
For i = LBound(dataArr) To UBound(dataArr)
result = result & i & ": " & dataArr(i) & Chr(10)
Next i
MsgBox resultEnd Sub
UBound・LBound関数の詳しい活用法については、侍エンジニア「VBAのUBoundとLBoundで配列の要素数を取得する方法」、だいたいIT「VBAのUBoundとLBoundの使い方」、LimeCode「VBAで配列の要素数を取得するUBound・LBound活用ガイド」も参考にしてください。
VBAをはじめとするExcel活用術や業務効率化のヒントは、kakiro-web.comでも幅広く解説しています。
まとめ
UBoundとLBoundを使えば配列要素数の取得は簡単
VBAで配列の要素数を取得するにはUBound(配列) - LBound(配列) + 1という公式が基本です。UBoundで最大インデックス、LBoundで最小インデックスを取得し、その差に1を加えることで正確な要素数が得られます。インデックスが0始まりでも1始まりでも対応できるため、常にこの公式を使う習慣をつけることが安全なコードへの近道です。
1次元・多次元配列での使い分けと注意点
多次元配列ではUBound(配列, 次元番号)の形式で各次元の要素数を個別に取得します。第1引数が行、第2引数が列に対応するため、Excelシートのデータ処理では行数・列数を別々に取得してループ処理に活用することが実務での基本パターンです。
動的配列も含めた実務での配列操作を効率化
動的配列は使用前に空かどうかを確認し、ReDim後は必ずUBoundで要素数を確認する習慣をつけましょう。Preserveを使ったデータ保持、LBound/UBoundを使ったインデックス依存しないループ処理を組み合わせることで、保守性の高いVBAコードが実現できます。
- 配列の要素数は
UBound(arr) - LBound(arr) + 1で取得する - UBoundは最大インデックス、LBoundは最小インデックスを返す
- 多次元配列は
UBound(arr, 1)・UBound(arr, 2)で各次元を個別取得する - ループは
For i = LBound(arr) To UBound(arr)とするとインデックスに依存しない - 動的配列のUBound実行前は空チェックを行いエラーを防ぐ
- ReDim Preserveは最後の次元のみサイズ変更可能という制約を覚えておく
- Option Baseの設定より明示的な「1 To n」形式での宣言を推奨する

