Excel VBAの配列インデックスをやさしく説明
配列は「同じ種類のデータを、番号付きでまとめて入れておける箱」の集まりです。VBAではこの「番号(インデックス)」を自由に決められるのが特徴。初心者がつまずきやすいポイントを、例題でかみ砕いて説明します。
配列の基本と「番号」の仕組み
- 配列とは: たくさんの値をひとまとめに管理するための入れ物。文字列なら文字列だけ、数値なら数値だけを並べて持てます。
- インデックス(番号): 配列の各要素にアクセスするための番号。VBAではこの開始番号を変えられます。
- デフォルトの開始番号: 多くの環境では「0から」始まります(例外もあるので後述のOption Baseを参照)。
例:0から始まる配列
Sub Example_DefaultIndex()
Dim fruits(3) As String ' 0~3の4個分
fruits(0) = "りんご"
fruits(1) = "みかん"
fruits(2) = "ぶどう"
fruits(3) = "いちご"
Dim i As Integer
For i = 0 To 3
Debug.Print fruits(i)
Next i
End Sub
VB開始番号を自由に決める「n To m」宣言
- 範囲指定: 宣言時に「最小値 To 最大値」で、番号の範囲を好きに決められます。
- メリット: 現実世界の番号やIDに合わせたいときに便利(例えば「社員IDが100~105」など)。
例:3~6で管理する
Sub Example_CustomBounds()
Dim members(3 To 6) As String ' インデックスは3,4,5,6
members(3) = "山田"
members(4) = "佐藤"
members(5) = "伊藤"
members(6) = "鈴木"
Dim i As Integer
For i = 3 To 6
Debug.Print members(i)
Next i
End Sub
VB範囲を安全に扱うためのLBound/UBound
- LBound: 最小のインデックス番号を返す関数。
- UBound: 最大のインデックス番号を返す関数。
- 利点: 範囲が変わってもコードが壊れない。「開始番号が0か1か」を気にせず書ける。
例:範囲に合わせた安全なループ
Sub Example_BoundsSafeLoop()
Dim scores(1 To 5) As Integer
Dim i As Integer
' 値を代入
For i = LBound(scores) To UBound(scores)
scores(i) = i * 10 ' 10,20,30,40,50
Next i
' 出力
For i = LBound(scores) To UBound(scores)
Debug.Print "No." & i & ": " & scores(i)
Next i
End Sub
VBOption Baseと混乱しない書き方
- Option Base 0/1: モジュールの先頭に書くと、範囲未指定の配列の「デフォルト開始番号」を0か1に設定できます。
- 注意点: チームやファイルをまたぐと混乱の元。範囲を指定する「n To m」を使うか、LBound/UBoundで書くと安全。
例:Option Base 1の影響
Option Base 1
Sub Example_OptionBase()
Dim arr(3) As String
' Option Base 1により、1~3の3要素になる(0は使えない)
arr(1) = "A"
arr(2) = "B"
arr(3) = "C"
End Sub
VBよくあるつまずきと回避策
- 範囲外アクセス: 存在しない番号にアクセスするとエラー。
- 対策: LBound/UBoundを使う。入力値から作るときは範囲チェックを行う。
- 開始番号の勘違い: 0始まりか1始まりかを混同。
- 対策: 宣言で「n To m」を明示するか、Option Baseを使わない前提で書く。
- Forループの端数ミス: 末尾が含まれない、または超える。
- 対策: For i = LBound(arr) To UBound(arr) を定型にする。
練習問題と解答例
練習1:1~12の月名を配列に入れて、3月と11月を表示
- 狙い: 任意開始の配列とループの基本。
Sub Practice_Months()
Dim months(1 To 12) As String
Dim i As Integer
months(1) = "1月": months(2) = "2月": months(3) = "3月"
months(4) = "4月": months(5) = "5月": months(6) = "6月"
months(7) = "7月": months(8) = "8月": months(9) = "9月"
months(10) = "10月": months(11) = "11月": months(12) = "12月"
Debug.Print months(3) ' 3月
Debug.Print months(11) ' 11月
' 全月表示(安全なループ)
For i = LBound(months) To UBound(months)
Debug.Print months(i)
Next i
End Sub
VB練習2:社員IDが100~105の配列を作り、偶数IDだけ表示
- 狙い: 現実の番号に合わせた範囲設定。
Sub Practice_EmployeeIDs()
Dim empName(100 To 105) As String
empName(100) = "Tanaka"
empName(101) = "Suzuki"
empName(102) = "Sato"
empName(103) = "Ito"
empName(104) = "Kato"
empName(105) = "Yamada"
Dim id As Integer
For id = LBound(empName) To UBound(empName)
If id Mod 2 = 0 Then
Debug.Print id & ": " & empName(id)
End If
Next id
End Sub
VB練習3:配列の合計を計算(開始番号が0かわからない環境でも動く)
- 狙い: LBound/UBoundで安全に合計。
Sub Practice_Sum()
Dim numbers(0 To 4) As Integer
Dim i As Integer, total As Long
numbers(0) = 3
numbers(1) = 7
numbers(2) = 2
numbers(3) = 9
numbers(4) = 5
For i = LBound(numbers) To UBound(numbers)
total = total + numbers(i)
Next i
Debug.Print "合計: "; total
End Sub
VB使い分けの指針
- 基本は0始まり+LBound/UBound: どの環境でも壊れにくい書き方。
- 業務IDに合わせたいときは「n To m」: 100~105など、実データの番号と揃えると理解しやすい。
- Option Baseはなるべく避ける: モジュール単位で挙動が変わり、後から読む人が混乱しやすい。
