VBAで大量のセルデータを処理する際、For Eachループなどでセルを一つずつ読み書きしていくと、データ量に比例して処理が非常に遅くなるという問題に直面します。
このパフォーマンス問題を解決する最も効果的で基本的な方法が、セル範囲の値を一度にまとめて「配列」に読み込み、VBAのメモリ上で高速に処理するというテクニックです。
この記事では、セルとVBA間のやり取りを最小限に抑え、マクロを劇的に高速化するための、この配列活用術を解説します。
なぜ配列を使うと速いのか?
VBAが遅くなる最大の原因の一つは、VBAのプログラムとExcelのワークシート間での頻繁なデータのやり取りです。
- 遅い方法(ループで1セルずつアクセス): 1万個のセルを処理する場合、VBAとExcel間で1万回の通信が発生します。これは、スーパーへ1万回買い物に行くようなもので、非常に非効率です。
- 速い方法(配列に一括代入): 最初に1回の通信で1万個のセルデータをすべてVBAのメモリ(配列)に読み込みます。メモリ上での処理は非常に高速なため、その後の処理は瞬時に完了します。これは、買い物リストを持ってスーパーへ1回だけ行くようなものです。
完成したVBAコード
以下が、C2セルを含む表領域(CurrentRegion)の値をすべて2次元配列に一度で読み込み、その内容の一部を表示するVBAコードです。
Sub LoadRangeIntoArray()
    ' 配列を格納するための変数は、必ずVariant型で宣言します
    Dim dataArray As Variant
    Dim sourceRange As Range
    
    '--- 1. 配列に読み込みたいセル範囲を特定 ---
    ' CurrentRegionは、Ctrl + * で選択される範囲と同じです
    Set sourceRange = ThisWorkbook.Worksheets("Sheet1").Range("C2").CurrentRegion
    '--- 2. セル範囲の.Valueを、Variant型の変数に一括で代入 ---
    ' この一行だけで、範囲の値が2次元配列として格納されます
    dataArray = sourceRange.Value
    '--- 3. 配列の要素にアクセスして内容を確認 ---
    ' 配列のインデックスは (行番号, 列番号) で、1から始まります
    MsgBox "配列の1行目、1列目の値は: " & dataArray(1, 1) & vbCrLf & _
           "配列の3行目、2列目の値は: " & dataArray(3, 2), vbInformation, "配列の内容確認"
           
    '--- (応用) メモリ上で配列をループ処理 ---
    Dim i As Long
    For i = 1 To UBound(dataArray, 1)
        ' 例: 3列目の値を大文字に変換してデバッグ出力
        Debug.Print UCase(dataArray(i, 3))
    Next i
End Sub
コードのポイント解説
① Dim dataArray As Variant
セル範囲から値を受け取る変数は、必ず**Variant型**で宣言する必要があります。StringやLongの配列としてDim dataArray() As Stringのように宣言すると、一括代入できずエラーになります。
② dataArray = sourceRange.Value
このコードの核心部分です。複数セルを含むRangeオブジェクトの.ValueプロパティをVariant型の変数に代入すると、VBAは自動的にその範囲の値を格納した2次元配列を作成します。
③ 配列のインデックス
Range.Valueで作成された配列には、以下のような特徴があります。
- 1から始まる: 配列のインデックスは、一般的なプログラミング言語で多い0からではなく、1から始まります。これはExcelの行番号・列番号の感覚と一致しており、直感的に扱えます。
- (行, 列) の2次元: 値にアクセスするには、dataArray(行番号, 列番号)のように指定します。
- 相対的な位置: 行番号・列番号は、元のワークシート上の絶対的な位置ではなく、取り込んだセル範囲の左上を(1, 1)とする相対的な位置になります。例えば、C2:D10の範囲を配列に取り込んだ場合、C2セルの値はdataArray(1, 1)に格納されます。
まとめ
VBAの処理速度を向上させるための最も重要なテクニックは、ワークシートへのアクセス回数を最小限に抑えることです。
- 処理したいデータ範囲の値を、myArray = myRange.Valueを使って、一度にVariant型の配列に読み込む。
- Forループなどの処理は、すべてメモリ上の配列に対して行う。
- (もし書き込みが必要なら)処理が完了した配列を、再びセル範囲に一度で書き戻す。
この「最初にまとめて読み込み、最後にまとめて書き出す」という考え方を徹底するだけで、VBAマクロのパフォーマンスは劇的に改善します。
【AI×就労支援】Neuro Dive(ニューロダイブ)で先端ITを学び、スペシャリストとしての就職を目指しませんか?
最後に宣伝をさせてください。
「AIやデータサイエンスを仕事にしたい」 「でも、独学には限界が…」
そんな方に知ってほしいのが、日本初の”先端IT特化型”就労移行支援『Neuro Dive』です。
IT職種への就職率80%超、職場定着率95%超という実績は、信頼の証。「学びたい」を「仕事」に繋げるプロフェッショナルです。
ご興味があれば、ぜひ公式サイトをチェックしてみてください。


 
			 
			 
			 
			 
			 
			 
			