【2026年7月最新】VBA配列の初期化完全ガイド|ReDim・Preserve・Array・Eraseを業務で徹底解説

【2026年7月最新】VBA配列の初期化完全ガイド|ReDim・Preserve・Array・Eraseを業務で徹底解説

「VBAの配列で初期化がうまくいかない」「ReDimとEraseの違いが分からない」——Excelマクロを書き始めると、こうした壁に早い段階でぶつかります。配列(はいれつ)は、VBAで業務自動化を本格的に進めるときに避けて通れない概念であり、特に「初期化」の操作は複数の方法があって混乱しやすいポイントです。

この記事では、VBA配列の初期化方法をErase・Array関数・ReDim・ReDim Preserveの4種類すべてについて、動作の違いから実際のコード例、業務での使いどころまで体系的に解説します。「配列は何となく分かるが、初期化で詰まる」という方から、「配列を使って業務Excelをもっと速くしたい」という方まで、読み終わると自信を持って配列を扱えるようになります。

代表菅澤 代表菅澤
弊社では社内の在庫管理・売上集計・顧客フィルタリングなど、あらゆるExcel業務マクロを開発しています。その中で配列を正しく初期化できないコードが原因のトラブルが多かった。この記事で一気に整理しています。
AI鬼管理山崎 AI鬼管理山崎
「配列の初期化」は奥が深いテーマです。EraseとReDimを混同するだけで全く違う動作になります。今日は固定長・可変長の違いも含めて、迷わず使えるレベルに整理していきます。

この記事で分かることをまとめると、次のとおりです。

✔️配列の基本概念:固定長・可変長の違いと、どちらを選ぶべきかの判断基準
✔️Erase:固定長と可変長で動作が異なる初期化命令の完全解説
✔️Array関数:値を一括代入できる初期化の書き方と注意点(Variant型必須)
✔️ReDim:実行時に要素数を変更する方法と「データが消える」挙動
✔️ReDim Preserve:データを保持したまま拡張する方法と多次元配列の制約
✔️業務での活用パターン:Excelシートとの高速データ入出力の実践テクニック
✔️よくあるエラーの原因と対処法:エラー番号9・13の根本原因
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理
📌 この記事の結論
【2026年7月最新】VBA配列の初期化完全ガイド|ReDim・Preserve・Array・Eraseを業務で徹底解説
VBA配列の初期化方法(Erase・Array・ReDim・ReDim Preserve)を完全解説。固定長・可変長配列の違いから多次元配列、Claude Code活用まで、業務で即使える実践ガイドです。

01 VBAの配列とは何か――業務視点で押さえる基礎 変数との違い、配列が必要になる場面、メモリ上の仕組みを整理する

プログラミングにおける「配列」とは、同じデータ型の複数の値を連続したメモリ領域にまとめて格納するデータ構造のことです。難しく聞こえますが、Excelで例えると「1つのセル=1つの変数、セルがまとまった行・列=配列」というイメージが近いです。社員10名の給与を管理するとき、salary1, salary2, salary3…という10個の変数を別々に作るより、salaries(0)〜salaries(9)という配列1つで管理するほうがコードが圧倒的にシンプルになります。

📚 用語解説

配列(はいれつ):同じデータ型の複数の値を連続したメモリ領域に格納するデータ構造。VBAでは「Dim arr(9) As Integer」のように宣言し、arr(0)〜arr(9)の10個の要素を一括管理します。ループ処理と組み合わせると大量データを高速に一括操作できます。

配列が特に威力を発揮するのは、「繰り返し処理(For文)」と組み合わせたときです。たとえば100件の顧客データをループで1件ずつ処理するとき、変数が100個あると100行のコードが必要ですが、配列なら「For i = 0 To 99」の1つのループで処理できます。コードが短くなるだけでなく、件数が変わってもループの終了条件を変えるだけで対応できるため、保守性も格段に上がります。これが配列を使う最大のメリットです。

VBAの配列には大きく分けて2種類あります。宣言時に要素数を決める「固定長配列」と、実行中に要素数を変更できる「可変長配列」です。どちらを選ぶかは「処理するデータの件数が事前に分かるかどうか」で判断します。月次の売上データが常に12ヶ月分であれば固定長、データベースから取得するレコード数が毎回変わるなら可変長が適切です。次のセクションで、それぞれの宣言方法を具体的に解説します。

✔️Excelのセル範囲データをVBAで一括処理したい
✔️顧客リストや商品リストをループで処理するマクロを書きたい
✔️ReDimやEraseを使っているのに思い通りに動かない
✔️固定長配列と可変長配列の使い分けで迷っている
✔️2次元配列でExcelシートを高速に操作したい
AI鬼管理山崎 AI鬼管理山崎
配列を覚えると「1件ずつセルにアクセスするマクロ」から「まとめて配列に読み込んで処理してまとめて書き出す」という高速パターンに移行できます。処理時間が文字通り10〜100倍速くなるケースは珍しくありません。

02 固定長配列と可変長配列の宣言方法 宣言の構文・インデックスの基本・スコープの考え方を押さえる

配列を使うには、まず「宣言」が必要です。VBAでは変数と同様に、使う前に「この名前でこの型の配列を使います」と宣言しなければなりません。宣言の仕方によって固定長か可変長かが決まり、その後の操作(Erase・ReDim・Array関数)も宣言の種類によって使えるもの・使えないものが変わってきます。

2-1. 固定長配列の宣言

固定長配列は、宣言時に要素数を括弧内に数値で指定します。たとえば「Dim scores(9) As Integer」と書くと、scores(0)〜scores(9)の10要素を持つInteger型の配列が作られます。要素数は「最大インデックス」を指定する点に注意してください。scores(9)は「0から始まって9番目まで」なので10要素になります。宣言時からメモリに領域が確保され、プログラム実行中に要素数を変えることはできません。

' 固定長配列の宣言例
Dim scores(9) As Integer        ' 10要素(scores(0)〜scores(9))
Dim names(4) As String          ' 5要素(names(0)〜names(4))
Dim prices(11) As Double        ' 12要素(月別データ 12ヶ月分)

' 宣言と同時に値を格納する例
Dim monthlyBudget(11) As Long
Dim i As Integer
For i = 0 To 11
    monthlyBudget(i) = 100000  ' 全月100,000円で初期化
Next i

📚 用語解説

固定長配列:宣言時に要素数を指定する配列。Dim arr(9) As Integerとすると、arr(0)〜arr(9)の10要素が確保されます。プログラム実行中に要素数を変更できません。データ件数が事前に確定している場合に使用します。固定長配列にReDimを使おうとするとコンパイルエラーになります。

2-2. 可変長配列の宣言

可変長配列は、宣言時の括弧内を空にして要素数を省略します。「Dim arr() As String」のように書くと、その時点ではメモリが確保されず、後からReDim命令で要素数を指定して初めて使えるようになります。データ件数がプログラム実行前に確定しない場合——データベースのクエリ結果件数、ユーザーが選択したファイルの行数など——に必ず使うパターンです。

' 可変長配列の宣言例
Dim customerNames() As String   ' 宣言時は要素数なし
Dim salesData() As Double        ' 宣言時は要素数なし

' 後でReDimで要素数を指定して使う
Dim recordCount As Long
recordCount = 500  ' 実行時に件数が確定
ReDim customerNames(recordCount - 1)  ' 0〜499の500要素を確保
ReDim salesData(recordCount - 1)

' 以降は固定長配列と同様にアクセスできる
customerNames(0) = "田中商事株式会社"
salesData(0) = 1250000

📚 用語解説

可変長配列:宣言時に要素数を指定せず、実行時にReDimで動的に変更できる配列。Dim arr() As Stringのように括弧内を空にして宣言します。データ件数が事前に不明な場合や、処理中に件数が変わる場合に使用します。誤って固定長として宣言するとReDimができなくなるため、設計段階でどちらを使うか決めておくことが重要です。

2-3. インデックスの基本とOption Base

VBAでは配列のインデックス(添え字)は標準で「0始まり」です。Dim arr(9) As Integerなら要素はarr(0)〜arr(9)の10個になります。これを「1始まり」にしたい場合は、モジュールの先頭に「Option Base 1」と記述します。すると「Dim arr(9) As Integer」はarr(1)〜arr(9)の9要素になります。ただしOption Base 1は同一モジュール内のすべての配列に影響するため、混乱を避けるためにも「0始まりで統一」し、要素数を計算するときにLBound()・UBound()関数を使う方が安全なコーディングスタイルです。

💡 LBound・UBoundで安全にインデックスを取得する

For i = 0 To 9 と決め打ちするより、For i = LBound(arr) To UBound(arr) と書く習慣をつけると、Option Base の設定変更やReDimで要素数が変わった際もコードを直さずに済みます。特にReDim Preserveで繰り返し拡張する処理では、UBound(arr)でのみ正確な件数が分かるため必須です。

宣言
Dim arr(N) As型
or Dim arr() As型
初期化/確保
ReDim(可変長)
or 宣言時に確保(固定)
データ格納
arr(i) = 値
ループで一括代入
処理
ループ・集計
フィルタ・変換
再初期化/解放
Erase or ReDim
で次回に備える
代表菅澤 代表菅澤
「固定長か可変長か」の判断で迷ったら、まず「件数が実行前に決まるか」を確認します。Excelのシート行数やDBのクエリ件数のように毎回変わるものは可変長一択。固定長を使って後からReDimしようとするとコンパイルエラーが出るので気をつけてください。

03 Eraseで配列を初期化する 固定長と可変長で挙動が変わる「一括リセット」命令の完全解説

Eraseは配列の全要素をリセットするためのVBA命令です。構文は「Erase 配列名」と非常にシンプルですが、固定長配列と可変長配列で動作が全く異なるため、この違いを正確に理解していないとバグの温床になります。VBAのエラーで最も多い「添え字が有効範囲にありません(エラー番号9)」の原因の多くが、このEraseの誤った使用から生じています。

3-1. 固定長配列へのErase:全要素がデフォルト値にリセット

固定長配列にEraseを使うと、全要素がそのデータ型のデフォルト値(Integer・Long・Doubleなどの数値型は0、String型は空文字""、Boolean型はFalse、Date型は1899/12/30)にリセットされます。配列のサイズ(要素数)はそのまま維持されるため、Erase後もarr(0)〜arr(N)に引き続きアクセスできます。「週次の集計値を月末に全件クリアして翌月のデータ入力に備える」といった用途に最適です。

' 固定長配列のErase例
Dim scores(4) As Integer
scores(0) = 85: scores(1) = 92: scores(2) = 78
scores(3) = 88: scores(4) = 95

Debug.Print scores(0)  ' → 85

Erase scores  ' 全要素をリセット

Debug.Print scores(0)  ' → 0(リセットされた)
Debug.Print scores(4)  ' → 0(要素数は維持されている)

' Erase後も同じサイズで引き続き使える
scores(0) = 70
Debug.Print scores(0)  ' → 70

3-2. 可変長配列へのErase:メモリが完全に解放される

可変長配列にEraseを使うと、配列のメモリが完全に解放されます。固定長のように「全要素が0になってサイズは維持」ではなく、「配列そのものがなかったことになる」イメージです。Erase後にarr(0)などにアクセスしようとすると「添え字が有効範囲にありません(エラー番号9)」が即座に発生します。可変長配列でEraseを使った後は、必ずReDimで再度要素数を設定してから使ってください。

' 可変長配列のErase例(注意が必要)
Dim names() As String
ReDim names(4)  ' 5要素を確保
names(0) = "田中": names(1) = "佐藤": names(2) = "山田"

Debug.Print names(0)  ' → 田中

Erase names  ' メモリが完全に解放される

' ここでアクセスするとエラー!
' Debug.Print names(0)  ' → エラー9: 添え字が有効範囲にありません

' Erase後に再利用するにはReDimが必要
ReDim names(9)  ' 10要素で再確保
names(0) = "鈴木"  ' OK
⚠️ Erase使用時の最重要注意:可変長配列はメモリ解放される

可変長配列(Dim arr() As String)にEraseを使うと、配列のメモリが完全に解放されます。この後arr(0)にアクセスすると「添え字が有効範囲にありません(エラー番号9)」が発生します。Erase後は必ずReDimで再初期化してから使ってください。このパターンはVBAのバグで最もよく見かける原因の一つです。

3-3. データ型別のErase後のデフォルト値

データ型Erase後の値用途の目安
Integer / Long / Double0(ゼロ)数値集計用配列のリセット
String""(空文字)氏名・コード等の文字列配列のリセット
BooleanFalseフラグ管理配列のリセット
Date1899/12/30日付配列のリセット(ほぼ使わない)
ObjectNothingオブジェクト参照配列の解放
VariantEmpty型不定の配列のリセット
AI鬼管理山崎 AI鬼管理山崎
EraseはよくFor文で全要素に0を代入するコードと比較されます。機能的には同じですが、Eraseの方がコードが短くVBAランタイム側で最適化されるため処理も速いです。配列を一括リセットするときは迷わずEraseを使ってください。
✔️固定長配列にEraseを使うと:全要素がデフォルト値にリセット、サイズは維持
✔️可変長配列にEraseを使うと:メモリ完全解放、Erase後はReDimが必須
✔️String型はErase後に""(空文字)、数値型は0になる
✔️Erase後の可変長配列にアクセスするとエラー番号9が発生する
✔️オブジェクト配列をEraseするとNothingが代入されてメモリリークを防げる
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

04 Array関数で配列を初期化する 複数の値を一行で代入できる初期化の書き方と注意点

Array関数は、括弧内にカンマ区切りで値を並べると、それらの値を格納した配列を一度に生成して返す関数です。「Dim months As Variant: months = Array("1月", "2月", ..., "12月")」のように、宣言と代入を実質1〜2行で書けるため、あらかじめ値が決まっているマスターデータ(曜日名・月名・部署コード・ステータスリスト等)を配列に入れる際に最も便利な方法です。

4-1. Array関数の基本構文

' Array関数の基本例
Dim weekdays As Variant
weekdays = Array("月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日", "日曜日")

' インデックスは0始まり
Debug.Print weekdays(0)  ' → 月曜日
Debug.Print weekdays(6)  ' → 日曜日

' 月名リストの例
Dim monthNames As Variant
monthNames = Array("1月", "2月", "3月", "4月", "5月", "6月", _
                   "7月", "8月", "9月", "10月", "11月", "12月")
Debug.Print monthNames(0)   ' → 1月(0始まり)
Debug.Print monthNames(11)  ' → 12月

' 数値の配列
Dim taxRates As Variant
taxRates = Array(0.08, 0.10, 0.10)  ' 2014年・2019年・現在の消費税率

📚 用語解説

Array関数:VBA組み込みの関数。括弧内にカンマ区切りで値を列挙すると、それらを格納したVariant型の配列を返します。戻り値はVariant型の変数でのみ受け取れます。インデックスはデフォルトで0始まりですが、Option Base 1を指定すると1始まりになります。

4-2. 必須ルール:受け取る変数はVariant型

Array関数を使う際の重要なルールが1つあります。戻り値を受け取る変数は必ずVariant型で宣言しなければなりません。IntegerやString等の具体的な型で宣言した変数にArray関数の結果を代入しようとすると、「型が一致しません(エラー番号13)」が発生します。このエラーはArray関数を初めて使う方がほぼ確実に一度は踏むので、「Array関数を使うときはVariant型」と覚えておいてください。

' NG例:String型で受け取ろうとするとエラー
' Dim wrongVar() As String
' wrongVar = Array("A", "B", "C")  ' エラー13: 型が一致しません

' OK例:Variant型で受け取る
Dim correctVar As Variant
correctVar = Array("A", "B", "C")  ' 正常動作

' UBound・LBoundで要素数を確認できる
Debug.Print LBound(correctVar)  ' → 0
Debug.Print UBound(correctVar)  ' → 2(3要素なのでインデックス0〜2)

' Forループで全要素にアクセス
Dim i As Integer
For i = LBound(correctVar) To UBound(correctVar)
    Debug.Print correctVar(i)  ' A, B, C の順に出力
Next i

4-3. 業務での実践活用:マスターデータ定義

Array関数が特に威力を発揮するのは、システム全体で共通して使う「マスターデータの定義」です。たとえば業務ステータスのコードリスト、部署名、商品カテゴリなどを配列として定義しておくと、マクロ全体でその配列を参照するだけで済みます。値の変更が必要なときもArray関数の1行を修正するだけで全処理に反映されるため、コードの保守性が大幅に向上します。

' 業務での活用例:ステータスコードのマスター配列
Sub ProcessOrders()
    ' 受注ステータスのマスター配列(Array関数で一括定義)
    Dim statusCodes As Variant
    statusCodes = Array("未処理", "処理中", "出荷済", "完了", "キャンセル")

    ' カテゴリマスター
    Dim categories As Variant
    categories = Array("電子部品", "機械部品", "消耗品", "備品", "サービス")

    ' シートのデータを1件ずつ確認してステータスを検証
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("受注データ")
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Dim r As Long
    For r = 2 To lastRow
        Dim status As String
        status = ws.Cells(r, 3).Value  ' C列のステータス

        ' マスター配列に一致するか確認
        Dim isValid As Boolean
        isValid = False
        Dim s As Integer
        For s = LBound(statusCodes) To UBound(statusCodes)
            If status = statusCodes(s) Then
                isValid = True
                Exit For
            End If
        Next s

        If Not isValid Then
            ws.Cells(r, 3).Interior.Color = RGB(255, 200, 200)  ' 無効値を赤くハイライト
        End If
    Next r

    MsgBox "ステータス検証完了"
End Sub
💡 Array関数とSelect Caseの組み合わせ

配列をLoop内でのマッチングに使うだけでなく、Join関数と組み合わせると「1月,2月,...,12月」のようなカンマ区切り文字列に変換できます。また「Filter(配列, 検索文字)」関数と組み合わせると、配列から条件に合う要素だけを抽出した新しい配列を生成できます。これらの組み合わせが業務マクロでよく使われる実践パターンです。

代表菅澤 代表菅澤
Array関数は「設定値の辞書」として使うのが最もスマートです。弊社の在庫管理マクロでは、商品カテゴリコードのリストをArray関数で定義し、ループで照合しています。カテゴリが追加・変更された際も1行修正するだけで全マクロに反映されます。

05 ReDimで要素数を変更する 可変長配列の要素数を実行時に設定・変更する命令の使い方

ReDim(Re-Dimensionの略)は、可変長配列の要素数を実行時に設定・変更するための命令です。「Dim arr() As String」で宣言した可変長配列は、宣言直後はサイズ0の空の配列です。実際にデータを格納できる状態にするには、ReDimで要素数を確保してからでないと「添え字が有効範囲にありません」エラーが発生します。データベースから取得したレコード数、Excelシートの行数、ユーザーが入力した件数など、実行時に初めて判明する件数に対応するための必須命令です。

5-1. ReDimの基本構文

' ReDimの基本使用例
Dim customerData() As String  ' 可変長配列を宣言

' 実行時にデータ件数が確定する
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("顧客リスト")
Dim rowCount As Long
rowCount = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row - 1  ' ヘッダーを除いた件数

' 確定した件数でReDim
ReDim customerData(rowCount - 1)  ' 0〜rowCount-1のrowCount件を確保

' データを格納
Dim i As Long
For i = 0 To rowCount - 1
    customerData(i) = ws.Cells(i + 2, 1).Value  ' 2行目からデータ読み込み
Next i

Debug.Print "取得件数: " & (UBound(customerData) + 1) & "件"

' 2次元配列のReDim
Dim salesMatrix() As Double
ReDim salesMatrix(rowCount - 1, 3)  ' 行数×4列の2次元配列

📚 用語解説

ReDim:可変長配列(要素数なしで宣言した配列)の要素数を実行時に設定・変更するためのVBA命令。ReDimを実行するたびに配列の全要素がデフォルト値(数値は0、文字列は空文字)にリセットされます。データを保持したまま拡張したい場合はReDim Preserveを使います。固定長配列(Dim arr(9) As型)にReDimを使おうとするとコンパイルエラーになります。

5-2. 重要:ReDimを実行するとデータが消える

ReDimを実行するたびに、その配列の全要素がデフォルト値にリセットされます。これは固定長配列のEraseと同様の挙動です。「データを途中まで格納しておいて、途中でReDimして要素数を変えたい」という場合は、次のセクションで解説する「ReDim Preserve」が必要になります。このデータリセットの挙動を知らずにReDimを使うと、せっかく蓄積したデータが全て消えるバグが発生します。

' ReDimでデータが消える例
Dim arr() As Integer
ReDim arr(4)  ' 5要素を確保
arr(0) = 10: arr(1) = 20: arr(2) = 30

Debug.Print arr(0)  ' → 10

ReDim arr(9)  ' 再度ReDim(要素数を変更)

Debug.Print arr(0)  ' → 0(データが消えた!)

' データを保持したまま拡張したい場合はReDim Preserveを使う
ReDim arr(4)
arr(0) = 10: arr(1) = 20: arr(2) = 30

ReDim Preserve arr(9)  ' Preserveキーワード付き
Debug.Print arr(0)  ' → 10(データが保持されている)

5-3. 多次元配列のReDim

多次元配列をReDimで宣言する際は、全ての次元数を同時に指定します。たとえば売上データを「行(顧客数)×列(月数)」で管理する場合、ReDim salesData(customerCount-1, 11)のように2次元配列として確保します。重要な制限として、ReDim Preserve(データ保持)で多次元配列を拡張できるのは最後の次元のみです(次のセクションで詳述)。

' 多次元配列のReDim例
Dim matrix() As Double

' 顧客数が確定してから2次元配列を確保
Dim customerCount As Long
customerCount = 100  ' 100顧客

' 100行×12列(月別売上)の2次元配列
ReDim matrix(customerCount - 1, 11)

' データを格納
matrix(0, 0) = 1200000   ' 顧客0番の1月売上
matrix(0, 1) = 980000    ' 顧客0番の2月売上
matrix(99, 11) = 2100000 ' 顧客99番の12月売上

Debug.Print "行数: " & (UBound(matrix, 1) + 1)  ' → 100
Debug.Print "列数: " & (UBound(matrix, 2) + 1)  ' → 12
✔️ReDimは可変長配列(Dim arr() As型)にのみ使用可能
✔️ReDimを実行すると全要素がデフォルト値にリセットされる
✔️固定長配列(Dim arr(9) As型)にReDimを使うとコンパイルエラー
✔️多次元配列はReDim時に全次元を同時に指定する
✔️データを保持したまま拡張するにはReDim Preserveを使う(次のセクション参照)
AI鬼管理山崎 AI鬼管理山崎
ReDimを複数回呼ぶコードは、毎回全データリセットが走るため慎重に設計する必要があります。件数が完全に確定してからReDim一回で確保するのが理想です。「とりあえず大きめにReDimして後でPreserveで縮小」という手もあります。

06 ReDim Preserveでデータを保持したまま拡張する Preserveキーワードの使い方と多次元配列の制約

ReDim Preserveは、配列の現在のデータを保持したまま要素数を変更できる命令です。「ReDim」単体だと既存データが消えてしまいますが、「Preserve」キーワードを追加することで既存データを残しながらサイズ変更が可能になります。「データを1件ずつ動的に追加しながら、配列を都度拡張していく」という処理で必須の機能です。

6-1. ReDim Preserveの基本構文

' ReDim Preserveの基本例
Dim results() As String
Dim count As Long
count = 0

' データを1件ずつ追加していく処理(件数が実行時に増える例)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("データ")
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

Dim r As Long
For r = 2 To lastRow
    ' 条件に合うデータだけ配列に追加(例:売上100万円以上)
    If ws.Cells(r, 2).Value >= 1000000 Then
        ReDim Preserve results(count)  ' 1件分拡張(データ保持)
        results(count) = ws.Cells(r, 1).Value
        count = count + 1
    End If
Next r

Debug.Print "合格件数: " & count & "件"
If count > 0 Then
    Debug.Print "最初の合格顧客: " & results(0)
End If

6-2. 重要な制約:多次元配列は最後の次元のみ変更可能

ReDim Preserveには重要な制約があります。多次元配列の場合、変更できるのは最後の次元(一番右)のみです。2次元配列arr(行, 列)であれば、Preserveで変更できるのは列方向(2次元目)だけで、行方向(1次元目)は変更できません。もし行方向に動的に拡張したい場合は、最初から行と列の定義を転置(逆にする)して設計する必要があります。

' 2次元配列のReDim Preserve制約
Dim arr() As Integer
ReDim arr(2, 9)  ' 3行×10列

arr(0, 0) = 100  ' データを格納

' NG例:1次元目(行)を拡張しようとするとエラー
' ReDim Preserve arr(4, 9)  ' エラー! 1次元目は変更できない

' OK例:2次元目(列)を拡張するのはOK
ReDim Preserve arr(2, 14)  ' 3行×15列に拡張(データ保持)
Debug.Print arr(0, 0)  ' → 100(保持されている)

' 行方向に動的拡張したい場合は転置して設計する
' arr(列, 行) として、行方向の拡張を2次元目で表現する
⚠️ ReDim Preserveの罠:最後の次元しか変更できない

2次元配列arr(行, 列)に対して「ReDim Preserve arr(新しい行数, 列数)」と書くとエラーになります。Preserveで変更できるのは最後の次元(列方向)のみです。行方向に動的に追加したい場合は、配列の定義を転置して「arr(列インデックス, 行インデックス)」の形にするか、先に行数の上限を大きめにReDimしておいて最後にPreserveで縮小する設計を使ってください。

ReDim
全データリセット
要素数変更
ReDim
Preserve

データ保持
要素数変更
多次元制約
最後の次元
のみ変更可
パフォーマンス
ループ内は
避ける

6-3. パフォーマンス上の注意点

ReDim Preserveはループ内で1件ずつ実行するのは避けてください。ReDim Preserveのたびにメモリの再割り当て(既存データのコピー)が走るため、件数が多い(1000件以上)場合に処理速度が著しく低下します。10000件のデータで1件ずつPreserveを繰り返すと、体感できるほど遅くなります。推奨のパターンは「配列を大きめに初期確保→処理後に実件数でPreserveで縮小」の1回呼び出し方式です。

' 高速パターン:Preserveを1回だけ呼ぶ
Dim results() As String
Dim maxRows As Long
maxRows = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

' 上限を最大件数で先に確保(Preserveなし)
ReDim results(maxRows - 1)

Dim actualCount As Long
actualCount = 0
Dim r As Long
For r = 2 To maxRows
    If ws.Cells(r, 2).Value >= 1000000 Then
        results(actualCount) = ws.Cells(r, 1).Value
        actualCount = actualCount + 1
    End If
Next r

' 最後に実件数でPreserveを1回だけ実行(余分な領域を切り落とす)
If actualCount > 0 Then
    ReDim Preserve results(actualCount - 1)
End If
Debug.Print "合格件数: " & actualCount
代表菅澤 代表菅澤
Preserveをループ内で使うのは「毎回会社引越しするようなもの」です。荷物が1件増えるたびにオフィス全体を引っ越すと膨大な時間がかかる。最初から大きな部屋を借りて、最後に必要な分だけ縮小する方が圧倒的に効率的です。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

07 多次元配列の初期化と業務活用 Excelシートデータとの連携・高速入出力パターンを解説

業務でVBA配列を使うとき、最も頻繁に登場するのが「2次元配列」です。Excelのシートデータは本質的に「行×列」の2次元構造なので、シートから読み込んだデータを2次元配列で管理することで、ループ処理も表形式のまま扱えます。ここでは、2次元配列の初期化から、Excelシートとの高速データ入出力まで実践的に解説します。

7-1. 2次元配列の宣言と初期化

' 2次元固定長配列
Dim salesData(99, 3) As Double   ' 100行×4列(顧客ID、1Q、2Q、3Q)

' 2次元可変長配列
Dim dynamicData() As String
Dim rowCount As Long, colCount As Long
rowCount = 200: colCount = 5
ReDim dynamicData(rowCount - 1, colCount - 1)

' Eraseで2次元配列を初期化
' 固定長なら全要素リセット、可変長なら解放
Erase salesData    ' 固定長:全要素が0にリセット(サイズ維持)
Erase dynamicData  ' 可変長:解放(再利用にはReDimが必要)

📚 用語解説

2次元配列:2つの添字(インデックス)でアクセスする配列。arr(行番号, 列番号)の形で要素を指定します。Excelのシート(行×列)と同じ構造なので、セル範囲データの操作に最適です。VBAでは最大60次元まで定義できますが、実務では2次元がほとんどです。

7-2. Excelシートと配列の高速入出力

VBAで大量データを処理するときの最重要テクニックが「配列の一括入出力」です。通常、1000行のデータをループで1行ずつ処理すると1000回セルにアクセスしますが、Range.Valueプロパティを使うと1回の操作でシート全体を2次元配列に読み込めます。この方法と1件ずつセルを読む方法では、処理速度が10〜100倍変わることがあります。Excelマクロの高速化で最初に覚えるべき最重要パターンです。

' 高速パターン:シートデータを一括配列に読み込む
Sub FastArrayProcess()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("売上データ")

    ' 最終行を取得
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' Range.Valueで一括読み込み(1回のセルアクセスで全データ取得)
    Dim data As Variant
    data = ws.Range("A2:D" & lastRow).Value  ' A2:D列×lastRow行を一発取得
    ' dataは(1〜lastRow-1, 1〜4)の2次元Variant配列(1始まり)

    ' 配列上で処理(セルへのアクセスなし=高速)
    Dim result() As Double
    ReDim result(1 To lastRow - 1, 1 To 2)  ' 結果格納用

    Dim r As Long
    For r = 1 To lastRow - 1
        result(r, 1) = data(r, 1)          ' 顧客ID
        result(r, 2) = data(r, 2) * 1.1    ' 売上に10%加算
    Next r

    ' 一括書き込み(1回のセルアクセスで全データ書き出し)
    Dim wsOut As Worksheet
    Set wsOut = ThisWorkbook.Sheets("結果")
    wsOut.Range("A2").Resize(lastRow - 1, 2).Value = result

    MsgBox "処理完了(" & lastRow - 1 & "件)"
End Sub
💡 Range.Valueで取得した配列は1始まり

ws.Range("A1:C10").Valueで取得した2次元Variant配列のインデックスは、1始まり(arr(1,1)〜arr(10,3))になります。通常の配列宣言(Dim arr(9))の0始まりとは異なるので注意してください。LBound(data, 1)でもLBound(data, 2)でも「1」が返ります。この仕様を知らずにarr(0,0)でアクセスしようとするとエラー9が発生します。

AI鬼管理山崎 AI鬼管理山崎
弊社の月次売上集計マクロを改善したとき、1件ずつセルを読むロジックから配列の一括読み込みに切り替えただけで、処理時間が18分から25秒に短縮されました。件数が多い業務マクロでは配列の一括入出力は必須です。
シート全体を
一括読み込み

Range.Value→
2次元配列化
配列上で
処理実行

ループ・フィルタ
集計・変換
結果配列に
格納

別の配列に
結果を書く
一括書き込み
配列→Range.Value
で1回書き出し

この「読み込み→配列処理→書き出し」のパターンを使うと、セルへのアクセス回数が「全件数×2(読み書き)」から「2回(一括読み込み・一括書き出し各1回)」に激減します。1000件なら2000回→2回、10000件なら20000回→2回です。Excelマクロが遅くて困っている場合、原因の多くがこのセルアクセス過多にあり、配列への切り替えで劇的に改善されます。

08 よくあるエラーと対処法 配列関連のエラー番号と根本原因・修正方法を網羅

VBAの配列処理では、特定のパターンのエラーが繰り返し発生します。エラーメッセージだけ見ると分かりにくいですが、原因のパターンは限られているので、一度覚えれば素早くデバッグできるようになります。ここでは配列関連のよくあるエラーとその対処法を整理します。

エラー番号メッセージ主な原因対処法
エラー9添え字が有効範囲にありません①未ReDimの可変長配列にアクセス ②Eraseで解放後にアクセス ③宣言した上限インデックスを超えたアクセスUBound()で上限確認、ReDim前にアクセスしていないか確認
エラー13型が一致しませんArray関数の戻り値をVariant型以外で受け取った受け取り変数をVariant型で宣言する
コンパイルエラー配列はすでに次元化されています固定長配列にReDimを使ったDim arr() As型(要素数なし)で可変長として宣言し直す
エラー1004指定されたRangeが正しくありません(関連)配列インデックスの計算ミスでシート範囲がずれるUBound/LBoundで実際の要素数を確認してからRange指定

8-1. エラー番号9「添え字が有効範囲にありません」の対処

最も頻繁に発生するエラーです。原因は主に3パターンに絞られます。①宣言しただけでReDimしていない可変長配列のインデックスにアクセスした、②Eraseで解放された可変長配列にアクセスした、③ループカウンタがUBound()を超えた——です。デバッグ時は、エラーが発生した行の配列名を確認し、その配列の宣言・ReDim・Erase の状況を上からトレースすることで原因が特定できます。

' エラー9の典型パターンと対処法

' パターン1:ReDim前にアクセス
Dim arr() As Integer
' arr(0) = 10  ' ← エラー9! ReDimがまだ
ReDim arr(9)
arr(0) = 10   ' OK

' パターン2:Erase後にアクセス
ReDim arr(9)
arr(0) = 50
Erase arr     ' 可変長配列は解放される
' arr(0) = 10  ' ← エラー9! 再度ReDimが必要
ReDim arr(9)
arr(0) = 10   ' OK

' パターン3:インデックスオーバー
ReDim arr(4)  ' 0〜4の5要素
' arr(5) = 99  ' ← エラー9! 上限は4
arr(4) = 99   ' OK

' 安全なアクセスパターン
If UBound(arr) >= 5 Then
    arr(5) = 99
End If
⚠️ 防御的プログラミング:アクセス前にUBoundで確認

「この配列にデータは入っているか」を確認したい場合、VBAには専用の関数がないため、On Error Resume Nextを使うか、カウンター変数で件数を管理するのが一般的です。配列がReDimされているかどうかを確認するには「If Not IsEmpty(arr) Then」(Variant型の場合)または件数管理変数を使ってください。

8-2. 防御的なコーディングパターン

' 安全な配列処理の定型パターン
Sub SafeArrayProcess()
    Dim data() As String
    Dim count As Long
    count = 0  ' 件数管理変数(配列の有効要素数を別途管理)

    ' ...データ収集処理...
    ' count > 0 の場合のみ、data(0)〜data(count-1)が有効

    ' 件数チェックしてから処理
    If count = 0 Then
        MsgBox "データがありません"
        Exit Sub
    End If

    ' 安全にループ
    Dim i As Long
    For i = 0 To count - 1  ' countで管理(UBoundより安全)
        Debug.Print data(i)
    Next i
End Sub
代表菅澤 代表菅澤
エラーが出てもあわてないこと。Claude Codeにエラーメッセージと該当コードをそのまま貼り付けて「このエラーの原因と対処法を教えて」と聞けば、即座にピンポイントで回答してくれます。自力でデバッグするより10倍速い場合がほとんどです。
✔️エラー9の確認:対象配列のReDimが済んでいるか、Eraseで解放済みでないか
✔️エラー13の確認:Array関数の受け取り変数がVariant型か
✔️コンパイルエラー「すでに次元化」:固定長配列にReDimしようとしていないか
✔️多次元配列Preserve失敗:最後の次元以外を変更しようとしていないか

09 Claude CodeでVBAコードを自動生成する AI活用でVBAの壁を越える:非エンジニアでもマクロが書ける

ここまで読んで「VBAの配列は理解できてきたが、自分でゼロからコードを書くのはまだハードルが高い」と感じている方もいるかもしれません。そこで弊社が実践しているのが、Claude Codeを活用したVBAコードの自動生成です。配列処理のような少し複雑なコードも、業務の要件を日本語で説明するだけでClaude Codeが正確に書いてくれます。

Claude Codeはターミナル(コマンドライン)上で動くAIエージェントですが、VBAのコード生成においては「自然な日本語で業務要件を説明→配列を使った最適なVBAコードを生成」という形で活用できます。ReDimを使うべきかReDim Preserveを使うべきか、2次元配列が適切かどうか、という設計判断まで含めてAIが考えてくれます。

代表菅澤 代表菅澤
弊社では社内の在庫管理・売上集計・顧客フィルタリングなどのExcel業務マクロをほぼ全てClaude Codeに書かせています。「A列の顧客コードで重複排除してB列の金額を合算するマクロを配列を使って高速に書いて」と言うだけで、ReDim Preserveまで使った本格的なコードが出てきます。

9-1. Claude Codeへの効果的な指示の書き方

VBAの配列を使ったコード生成をClaude Codeに依頼する際のポイントは、業務のゴールと「データの性質」をセットで伝えることです。件数が毎回変わるのか固定なのか、2次元データなのか1次元なのか——こうした情報を伝えることで、Claude Codeが固定長か可変長か、ReDimかReDim Preserveかを適切に判断してコードを書いてくれます。

✔️「何をしたいか」を業務の言葉で説明する(例:「毎月のExcel売上シートを顧客別に集計したい」)
✔️「件数が毎月変わる」「常に12行固定」など、データの変動性を伝える(固定長・可変長の判断に直結)
✔️「処理後に結果を別シートに書き出したい」など出力先も明示する
✔️生成されたコードの日本語コメントを読んで、何をしているかを理解する
✔️動かない場合はエラーメッセージごとClaudeに貼り付けて「なぜエラーが出るか」を聞く
' Claude Codeへの指示例(入力テキスト)
' 「ExcelのSheet1にあるA列(顧客名)B列(売上額)のデータを
'  顧客名ごとに売上を合算してSheet2に出力するVBAマクロを、
'  配列とDictionaryを使って高速に書いてください。
'  データ件数は毎月変わります。」
'
' → Claude Codeが以下のような最適なコードを自動生成
'    (実際にはもっと詳細なコメント付きで生成される)

Sub SumSalesByCustomer()
    ' 可変長配列+Dictionaryで顧客別集計
    Dim ws1 As Worksheet, ws2 As Worksheet
    Set ws1 = ThisWorkbook.Sheets("Sheet1")
    Set ws2 = ThisWorkbook.Sheets("Sheet2")

    Dim lastRow As Long
    lastRow = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row

    ' 一括読み込み(高速化)
    Dim data As Variant
    data = ws1.Range("A2:B" & lastRow).Value

    ' Dictionaryで顧客別集計
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")

    Dim r As Long
    For r = 1 To UBound(data, 1)
        Dim key As String
        key = CStr(data(r, 1))
        If dict.Exists(key) Then
            dict(key) = dict(key) + data(r, 2)
        Else
            dict.Add key, data(r, 2)
        End If
    Next r

    ' 結果を配列に格納して一括書き出し
    Dim resultCount As Long
    resultCount = dict.Count
    Dim results() As Variant
    ReDim results(resultCount - 1, 1)

    Dim i As Long
    i = 0
    Dim k As Variant
    For Each k In dict.Keys
        results(i, 0) = k
        results(i, 1) = dict(k)
        i = i + 1
    Next k

    ws2.Range("A2").Resize(resultCount, 2).Value = results
    MsgBox "集計完了:" & resultCount & "顧客"
End Sub
💡 Claude Codeに「なぜこのコードにしたか」も聞く

コードが生成されたら「なぜReDimではなくDictionaryを使ったのか」「可変長配列を選んだ理由は?」と追加で聞くことができます。Claude Codeは設計判断の根拠も日本語で説明してくれるので、コードを読むだけでなく、なぜそう書くのかの理解も同時に深まります。

AI鬼管理山崎 AI鬼管理山崎
「VBAが書けなくても、業務マクロを作れた」という体験が学習の最短ルートです。Claude Codeに書いてもらったコードを読んでコメントを理解する——この繰り返しで、自然にVBAの配列の使い方も身についていきます。

非エンジニアの経営者・管理職の方がClaude Codeを活用してVBAを自動化するステップを整理すると、「業務課題の定義(何が面倒なのか)→Claude Codeへの日本語指示→生成されたコードを社内Excelに貼り付けて実行→動作確認→改善点があれば追加指示」というサイクルになります。プログラミングの知識がなくても、業務の要件を言語化できれば自動化が実現できる時代になっています。弊社(株式会社GENAI)では、こうしたClaude Codeを活用した業務自動化の設計・実装支援を「AI鬼管理」として提供しています。

Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

10 まとめ VBA配列の初期化を完全に使いこなすために

この記事では、VBA配列の初期化方法を4つの手段——Erase・Array関数・ReDim・ReDim Preserve——に分けて完全解説しました。最後にポイントを振り返ります。

✔️固定長配列(Dim arr(N)):要素数固定。Eraseで全要素リセット(サイズ維持)。ReDimは使用不可
✔️可変長配列(Dim arr()):要素数は後からReDimで設定。Eraseでメモリ解放(Erase後はReDimが必要)
✔️Erase:全要素リセット(固定長)またはメモリ解放(可変長)。固定長・可変長で挙動が違うことを必ず覚える
✔️Array関数:値を一括代入。受け取り変数はVariant型必須。マスターデータ定義に最適
✔️ReDim:可変長配列の要素数を実行時に設定・変更。実行するたびにデータがリセットされる
✔️ReDim Preserve:データを保持したまま要素数を変更。多次元配列は最後の次元のみ変更可
✔️高速化の定石:Range.Valueで一括読み込み→配列処理→Range.Valueで一括書き込み

配列の初期化を正確に理解することで、VBAコードの品質と処理速度が格段に向上します。「なんとなく動いているが、時々エラーが出る」という状況は、ほとんどの場合がEraseとReDimの使い分けの理解不足か、固定長・可変長の混同から来ています。この記事で整理した4つの初期化方法をマスターすれば、そうした問題から解放されます。

代表菅澤 代表菅澤
配列を正しく使えるようになると、業務Excelのマクロが劇的に速くなります。弊社では月次集計処理が20分→1分以内になった事例が複数あります。配列の一括入出力パターンを一度覚えれば、どんなデータ量でも対応できます。

VBAのコードを自分で書くのが難しい場合は、Claude Codeに業務の要件を日本語で説明するだけで、配列を使った最適なコードを自動生成できます。「VBAは難しい」ではなく、「AIをうまく使えば非エンジニアでも業務自動化ができる」という時代になっています。弊社のAI鬼管理では、こうした自動化設計の無料相談を承っています。

VBAの業務自動化を、AI鬼管理が一緒に設計します

「Excelマクロで業務を自動化したいが、VBAが難しい」「配列を使った高速処理を自社に取り入れたい」という方に向けて、弊社ではClaude Codeを活用した業務自動化の設計から実装支援まで行っています。

AI鬼管理山崎 AI鬼管理山崎
「何から始めればいいか分からない」という方も、まずは無料相談で現状の業務フローをお聞かせください。VBAで自動化できる部分・Claude Codeに任せるべき部分を整理して、最短で成果が出るプランをご提案します。

NEXT STEP

この記事の内容を、あなたのビジネスで
実践してみませんか?

AI活用を自社で回せるようになりたい方へ

AI鬼管理

Claude Code・Cowork導入支援から業務設計・社内浸透まで実践ベースで伴走。「自社で回せる組織」を90日で作る経営者向けトレーニング。

よくある質問

Q. VBAの配列と変数の違いは何ですか?

A. 変数は1つの値しか格納できませんが、配列は同じデータ型の複数の値をインデックスで管理できます。10人の給与を管理するとき、変数が10個必要なところを配列1つで対応でき、ループ処理と組み合わせると大量データを効率的に処理できます。配列はデータ件数が増えてもコードを変えずに対応できる点が最大のメリットです。

Q. EraseとReDimを組み合わせる典型的な使い方はありますか?

A. ループ処理の途中で「一度全データをリセットして最初から入れ直す」場面でErase+ReDimの組み合わせが使われます。たとえば「月次バッチ処理で前月のデータを消去してから今月のデータを再格納する」処理では、可変長配列にErase(解放)→ReDim(今月の件数で再確保)→データ格納、という流れになります。

Q. 配列の要素数(件数)を取得するにはどうすればいいですか?

A. UBound(配列名)で最大インデックス、LBound(配列名)で最小インデックスを取得できます。要素数は「UBound(arr) - LBound(arr) + 1」で計算します。0始まりなら「UBound(arr) + 1」でも同じです。2次元配列の場合はUBound(arr, 1)で行数、UBound(arr, 2)で列数を取得できます。

Q. DictionaryやCollectionと配列はどう使い分けるべきですか?

A. 配列はインデックス(数値)でアクセスする順序付きのデータ構造です。Dictionaryはキー(文字列など)で高速検索ができます。「顧客IDで売上を集計する」ような「キーで検索・集約」が必要な処理はDictionaryが適しています。一方「Excelシートデータを行番号・列番号でそのまま扱う」ような「インデックスアクセスと一括入出力」が中心なら配列が適しています。

Q. 2次元配列を全件ループするにはどう書けばいいですか?

A. For r = LBound(arr, 1) To UBound(arr, 1): For c = LBound(arr, 2) To UBound(arr, 2): 処理 : Next c: Next r という二重ループが基本です。LBound/UBoundに第2引数(次元番号)を渡すことで行数・列数それぞれの上限が取得できます。Range.Valueで取得した配列は1始まりなのでLBoundは1になります。

Q. 配列の最大要素数(サイズ)に制限はありますか?

A. VBAの配列の最大要素数は、利用可能なメモリ量に依存します。理論上は整数の最大値(約21億)まで指定できますが、実際にはメモリが足りなくなる前に「メモリが不足しています」エラーが発生します。通常の業務処理(100万行以下)であれば制限を意識する必要はほとんどありません。

Q. VBAのコードをゼロから書くのが難しいのですが、AIを使って自動生成できますか?

A. できます。Claude Codeに「Excelのデータを配列で処理したい」という業務要件を日本語で説明すると、配列宣言・ReDim・ループ処理・一括入出力まで含んだ完全なVBAコードを生成してくれます。件数が変動するか固定かを伝えると、固定長・可変長の選択も自動判断されます。

AIAI鬼管理

AI鬼管理へのお問い合わせ

この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。

会社名を入力してください
業種を選択してください
お名前を入力してください
正しいメールアドレスを入力してください

1つ以上選択してください
1つ以上選択してください
月額コストを選択してください

約1時間のオンライン面談(Google Meet)です

空き枠を取得中...
面談日時を選択してください

予約確定後、Google Calendarの招待メールをお届けします。
しつこい営業は一切ございません。

監修 最終更新日: 2026年7月19日
菅澤孝平
菅澤 孝平 株式会社GENAI 代表取締役
  • AI業務自動化サービス「AI鬼管理」を運営 — Claude Code を活用し、経営者の業務を「AIエージェントに任せる仕組み」へ転換するパーソナルトレーニングを 伴走構築 で提供。日報・採用・問い合わせ対応・経費精算・議事録・データ集計・営業リスト等の定型業務を、AIに代行させる体制を経営者と一緒に作り込む
  • Claude Code 実装ノウハウを 経営者・法人クライアント に直接指導。生成AIを「便利ツール」ではなく 「業務を任せる存在」 として運用する手法を体系化
  • 「やらせ切る管理」メソッドの開発者。シンゲキ株式会社(2021年設立・鬼管理専門塾運営)にて累計3,000名以上の学習者を志望校合格に導いた管理メソッドを、AI × 経営者支援 に転用
  • 著書『3カ月で志望大学に合格できる鬼管理』(幻冬舎)、『親の過干渉こそ、最強の大学受験対策である。』(講談社)
  • メディア出演: REAL VALUE / カンニング竹山のイチバン研究所 / ええじゃないかBiz 他
  • 明治大学政治経済学部卒
現在は AI鬼管理(Claude Code活用の伴走型パーソナルトレーニング)を主事業とし、経営者と二人三脚で「AIに業務を任せる仕組み」を実装。「実行を強制する環境」を AI で構築する手法を、自社の実運用知見をもとに発信している。