Excel VBAでマクロを作成していると、
「セルの値を1つずつ処理すると遅い」「件数が増えると固まる」
といった問題に必ず直面します。
多くの場合、その原因は
セルを直接ループで参照していることにあります。
For i = 1 To 1000
Cells(i, 1).Value = Cells(i, 1).Value & "_A"
Next i
一見すると問題なさそうですが、この処理は
1000回、Excelシートとやり取りしています。
実務レベルでは、これが処理速度低下の最大要因になります。
そこで重要になるのが、
セルの値をいったん「変数配列」に取得し、配列上でループ処理する設計です。
この記事では、
- セルの値を配列に取得する意味
- 変数配列と2次元配列の基本
- ループ処理を安全・高速に行う方法
- 実務で壊れないテンプレート構成
- 大量データ・RPA連携を見据えた設計
までを、実務視点で徹底的に解説します。
目次
- ✅ なぜセルの値を変数配列に取得すべきなのか
- ・セル操作は想像以上に遅い
- ・配列に取得すればメモリ上で完結する
- ✅ 変数配列とは何かを正しく理解する
- ・単なる変数との違い
- ・Rangeを代入すると自動で配列になる
- ✅ セルの値を配列に取得する基本パターン
- ・縦1列のセルを配列に取得する
- ・横1行の場合も2次元配列
- ✅ 取得した変数配列をループ処理する基本
- ・行方向をループする基本形
- ・なぜ LBound / UBound が必須なのか
- ✅ 2次元配列として扱う理由と考え方
- ・ExcelのRangeは行×列の集合体
- ・実務でのメリット
- ✅ 複数列のセルを配列に取得して処理する方法
- ・複数列を一括取得する
- ・行×列の2重ループ
- ✅ 条件付きで変数配列をループ処理する方法
- ・空白を除外して処理する例
- ・特定条件を満たす行だけ処理する
- ✅ 処理結果を別の配列に格納する設計
- ・結果格納用配列を用意する
- ・ループ内で結果を代入
- ✅ 処理後に配列を一括でシートに書き戻す
- なぜ一括出力が重要なのか
- ✅ 実務でよく使うテンプレート(完成形)
- ✅ 大量データを扱う場合の高速化設定
- ✅ よくある失敗例と回避策
- ・失敗例① Cells参照と配列参照を混在
- ・失敗例② 行数を固定でループ
- ・失敗例③ 配列の次元を意識していない
- ✅ UiPath・RPA連携を見据えた配列設計
- ✅ まとめ:セルの値は必ず変数配列に取得して処理する
✅ なぜセルの値を変数配列に取得すべきなのか
VBA初心者の多くは、「For文でCellsを回せばいい」と考えがちです。
しかし実務では、この方法はすぐに限界を迎えます。
ここでは、なぜ配列取得が必須なのかを整理します。
この理由を理解していないと、後半のコードの価値が半減します。
まずは考え方をしっかり押さえてください。
・セル操作は想像以上に遅い
セルの値を1回取得するたびに、
VBAはExcelアプリケーションと通信しています。
- 件数が増える
- 列数が増える
この積み重ねで、処理時間は一気に膨らみます。
・配列に取得すればメモリ上で完結する
Dim arr As Variant
arr = Range("A2:A1000").Value
この1行で、
1000件分のセル値を一括でメモリに格納できます。
以降の処理は、すべてメモリ上で行われるため、
処理速度が大幅に向上します。
✅ 変数配列とは何かを正しく理解する
ここでいう「変数配列」とは、
セルの値を格納した配列変数のことを指します。
・単なる変数との違い
Dim val As String
val = Range("A1").Value
これは「1つの値」しか保持できません。
一方、配列は複数の値をまとめて扱えます。
Dim arr As Variant
arr = Range("A1:A5").Value
・Rangeを代入すると自動で配列になる
Excel VBAでは、RangeをVariant型に代入すると、
自動的に2次元配列として格納されます。
ここが非常に重要なポイントです。
✅ セルの値を配列に取得する基本パターン
まずは、最も基本となる書き方を押さえます。
・縦1列のセルを配列に取得する
Dim arr As Variant
arr = Range("A2:A10").Value
この時点で、arr は 2次元配列 になります。
- arr(行, 列)
- 列は常に 1
・横1行の場合も2次元配列
arr = Range("A1:E1").Value
- arr(1, 列)
1次元配列ではない点に注意してください。
✅ 取得した変数配列をループ処理する基本
配列に取得しただけでは意味がありません。
次に、正しいループ処理を理解します。
・行方向をループする基本形
Dim i As Long
For i = LBound(arr, 1) To UBound(arr, 1)
Debug.Print arr(i, 1)
Next i
ポイント
- LBound / UBound を必ず使う
- 行数を固定値で書かない
・なぜ LBound / UBound が必須なのか
配列の開始インデックスは、
Option Base や取得方法によって変わります。
For i = 1 To 10
この書き方は、実務では非常に危険です。
参考:【VBA】ExcelVBAのLBound関数・UBound関数を使用する配列の基本
✅ 2次元配列として扱う理由と考え方
多くの方が混乱するのが、
「1列なのになぜ2次元なのか」という点です。
・ExcelのRangeは行×列の集合体
ExcelのRangeは、
常に行と列の組み合わせで構成されています。
そのため、VBA側でも2次元配列として扱われます。
・実務でのメリット
- 列を増やしても対応しやすい
- 拡張・修正に強い
✅ 複数列のセルを配列に取得して処理する方法
実務では、複数列を同時に扱うケースがほとんどです。
・複数列を一括取得する
Dim arr As Variant
arr = Range("A2:C10").Value
- arr(行, 列)
・行×列の2重ループ
Dim i As Long, j As Long
For i = LBound(arr, 1) To UBound(arr, 1)
For j = LBound(arr, 2) To UBound(arr, 2)
Debug.Print arr(i, j)
Next j
Next i
実務での注意点
- 不要な列は処理しない
- 列番号を定数化すると保守性が向上
参考:【VBA】For文:二重ループから抜ける方法
✅ 条件付きで変数配列をループ処理する方法
実務では、必ず条件分岐が発生します。
・空白を除外して処理する例
For i = LBound(arr, 1) To UBound(arr, 1)
If Trim(arr(i, 1)) <> "" Then
' 処理
End If
Next i
・特定条件を満たす行だけ処理する
If arr(i, 2) = "完了" Then
' 完了データのみ処理
End If
✅ 処理結果を別の配列に格納する設計
実務では、
「元データを壊さず、加工結果を別に持つ」
設計が重要です。
・結果格納用配列を用意する
Dim result() As Variant
ReDim result(1 To UBound(arr, 1), 1 To 1)
・ループ内で結果を代入
result(i, 1) = arr(i, 1) & "_完了"
✅ 処理後に配列を一括でシートに書き戻す
配列処理の最後は、必ず一括出力します。
Range("D2").Resize(UBound(result, 1), 1).Value = result
なぜ一括出力が重要なのか
- セル操作回数を最小化
- 処理速度が大幅に向上
- 画面更新によるちらつきを防止
✅ 実務でよく使うテンプレート(完成形)
Sub GetCellValueToArrayAndLoop()
Dim src As Variant
Dim result() As Variant
Dim i As Long
src = Range("A2:A100").Value
ReDim result(1 To UBound(src, 1), 1 To 1)
For i = LBound(src, 1) To UBound(src, 1)
If Trim(src(i, 1)) <> "" Then
result(i, 1) = src(i, 1) & "_処理済"
End If
Next i
Range("B2").Resize(UBound(result, 1), 1).Value = result
End Sub
このテンプレートの強み
- 行数が変わっても壊れない
- 高速
- 実務で再利用しやすい
✅ 大量データを扱う場合の高速化設定
配列処理と必ずセットで行う設定があります。
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
処理後は必ず元に戻します。
参考:【VBA】Application.ScreenUpdatingプロパティの使用方法と特徴
✅ よくある失敗例と回避策
・失敗例① Cells参照と配列参照を混在
→ 処理速度が低下
・失敗例② 行数を固定でループ
→ データ欠損・エラー
・失敗例③ 配列の次元を意識していない
→ バグの温床
✅ UiPath・RPA連携を見据えた配列設計
最近の実務では、
Excel VBAは RPAの前処理として使われることが増えています。
- RPA:ファイル取得・登録
- VBA:配列取得・ループ加工
この役割分担により、
フロー全体の安定性が大きく向上します。
✅ まとめ:セルの値は必ず変数配列に取得して処理する
- セル直接ループは遅く不安定
- 配列に一括取得することで高速化
- Range取得は2次元配列になる
- ループは LBound ~ UBound を使う
- 条件分岐・空白対策を必ず入れる
- 出力も一括で行う
- RPA連携を見据えた設計が実務では有効
セルの値を変数配列に取得し、
配列上でループ処理できるようになると、
Excel VBAは一気に実務レベルに到達します。
ぜひこの記事のテンプレートをベースに、
自分のマクロを配列処理へ書き換えてみてください。
処理速度と安定性の違いを、確実に実感できるはずです。