配列×ループ
配列に読み込んでからループで処理すると、セルへ何度もアクセスするより圧倒的に速く・安全に動きます。ここでは、初心者がつまずきやすい宣言・代入・取り出しから、2次元配列(Range.Value)、高速一括書き戻しまでを例題付きで解説します。
基本:1次元配列とループ
Sub Array1D_Basic()
Dim names(0 To 2) As String '固定長配列(3要素)
names(0) = "田中"
names(1) = "佐藤"
names(2) = "鈴木"
Dim i As Long
For i = LBound(names) To UBound(names)
Cells(i + 2, "A").Value = names(i)
Next i
End Sub
VB- ポイント:
- LBound/UBound: 配列の下限・上限を取得して安全に回す。
- 固定長配列: 要素数が決まっているときに簡単。
可変長配列(ReDim)と拡張
Sub Array1D_Dynamic()
Dim arr() As Double '可変長
ReDim arr(1 To 5) '必要になったらサイズ確保
Dim i As Long
For i = 1 To 5
arr(i) = i * 10
Next i
'サイズを増やす(中身保持)
ReDim Preserve arr(1 To 8)
arr(6) = 999
For i = LBound(arr) To UBound(arr)
Cells(i + 1, "B").Value = arr(i)
Next i
End Sub
VB- ポイント:
- ReDim: 実行時にサイズ変更。
- Preserve: 既存データを保持。最終次元のみ拡張可能。
2次元配列:Range.Valueを読み込む(最速の定番)
Sub Array2D_FromRange()
Dim rg As Range
Set rg = Range("C2:F1000")
Dim data As Variant
data = rg.Value '2次元配列(1-based)へ
Dim r As Long, c As Long
For r = 1 To UBound(data, 1)
For c = 1 To UBound(data, 2)
If IsNumeric(data(r, c)) Then
data(r, c) = data(r, c) * 1.1 '例:10%上乗せ
End If
Next c
Next r
rg.Value = data '一括で書き戻し
End Sub
VB- ポイント:
- Variant配列: Range.Valueは2次元Variant配列で受けるのが基本。
- 一括書き戻し: セルへの個別アクセスを避けて高速化。
For Eachで配列を回す(Variant配列)
Sub Array_ForEach()
Dim arr As Variant
arr = Array("A", "B", "C") '1次元のVariant配列
Dim v As Variant, i As Long
i = 2
For Each v In arr
Cells(i, "D").Value = v
i = i + 1
Next v
End Sub
VB- ポイント:
- Array関数: 手早く配列を作れる(Variant配列)。
- For Each: 要素を直感的に処理。添字が不要。
実務テンプレート:配列×ループの王道
1) 大量データを配列で読み込み→計算→一括書き戻し
'1) 大量データを配列で読み込み→計算→一括書き戻し
Sub Template_ArrayBatchCalc()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim rg As Range: Set rg = Range("A2:D50000")
Dim v As Variant: v = rg.Value
Dim r As Long
For r = 1 To UBound(v, 1)
'数量=C(3列目), 単価=D(4列目)→金額をB(2列目)に書く例
If IsNumeric(v(r, 3)) And IsNumeric(v(r, 4)) Then
v(r, 2) = v(r, 3) * v(r, 4)
End If
Next r
rg.Value = v
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
VB2) 片方向の整形処理(Trimや大文字化を配列に適用)
'2) 片方向の整形処理(Trimや大文字化を配列に適用)
Sub Template_CleanText()
Dim rg As Range: Set rg = Range("B2:B10000")
Dim v As Variant: v = rg.Value
Dim r As Long
For r = 1 To UBound(v, 1)
If Not IsEmpty(v(r, 1)) Then
v(r, 1) = UCase$(Trim$(CStr(v(r, 1))))
End If
Next r
rg.Value = v
End Sub
VB- ポイント:
- 速度ラップ: 画面更新と再計算OFF→ONで体感速度UP。
- 型変換: 文字列処理は CStr、数値は IsNumericチェックが安全。
行列ループ:2次元配列で条件塗り分け
Sub Array_ColorByThreshold()
Dim rg As Range: Set rg = Range("E2:H2000")
Dim v As Variant: v = rg.Value
Dim r As Long, c As Long
For r = 1 To UBound(v, 1)
For c = 1 To UBound(v, 2)
If IsNumeric(v(r, c)) Then
If v(r, c) >= 80 Then
'値側ではなく後でセルへ反映する指示列を使う例
v(r, c) = v(r, c) '値はそのまま
End If
End If
Next c
Next r
rg.Value = v
'色はセルに対して適用(書式は一括代入できないため直接セルへ)
Dim r2 As Long, c2 As Long
For r2 = 1 To rg.Rows.Count
For c2 = 1 To rg.Columns.Count
If IsNumeric(rg.Cells(r2, c2).Value) Then
If rg.Cells(r2, c2).Value >= 80 Then
rg.Cells(r2, c2).Interior.Color = RGB(198, 239, 206)
Else
rg.Cells(r2, c2).Interior.Color = RGB(255, 199, 206)
End If
End If
Next c2
Next r2
End Sub
VB- ポイント:
- 値は配列で、書式はセルへ: 値の計算は配列で最速、書式はセル操作が必要。
例題で練習
例題1:CSV風データをSplitで配列化→行へ書き出し
Sub Example_SplitCsvRow()
Dim line As String
line = "東京,営業A,120,800"
Dim parts As Variant
parts = Split(line, ",")
Dim i As Long
For i = LBound(parts) To UBound(parts)
Cells(2, i + 1).Value = parts(i)
Next i
End Sub
VB例題2:選択範囲を配列化して「10%値引き」
Sub Example_DiscountSelection()
If TypeName(Selection) = "Range" Then
Dim v As Variant
v = Selection.Value
Dim r As Long, c As Long
For r = 1 To UBound(v, 1)
For c = 1 To UBound(v, 2)
If IsNumeric(v(r, c)) Then v(r, c) = v(r, c) * 0.9
End If
Next r
Selection.Value = v
End If
End Sub
VB例題3:2列を配列で読み込んで結合文字列を作る
Sub Example_ConcatTwoCols()
Dim rg As Range: Set rg = Range("A2:B1000")
Dim v As Variant: v = rg.Value
Dim out() As Variant
ReDim out(1 To UBound(v, 1), 1 To 1)
Dim r As Long
For r = 1 To UBound(v, 1)
out(r, 1) = Trim$(CStr(v(r, 1))) & " - " & Trim$(CStr(v(r, 2)))
Next r
Range("C2").Resize(UBound(out, 1), 1).Value = out
End Sub
VB実務の落とし穴と対策
- 配列のインデックス起点: Range.Valueの2次元配列は 1 始まり。Array()や固定長の多くは 0 始まり。LBound/UBoundで境界を必ず取る。
- 型の混在: 数値と文字列が混ざると計算時にエラーになりやすい。IsNumeric/CStr/Val を適切に使う。
- Preserveの制約: ReDim Preserveは最終次元しか伸縮できない。構造変更が必要なら新配列へコピー。
- 書式操作のコスト: 背景色・フォントなどはセルアクセスが必要。値計算は配列、一括色付けは対象範囲を特定して最小限に。
- 速度最適化の基本: 配列で一括読み書き、ScreenUpdating/CalculationのOFF→ON、Select/Activateを使わない。
Sub SpeedWrap_Array()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'…配列×ループの本処理…
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
VB