【2026年7月最新】VBA配列の初期化完全ガイド|ReDim・Preserve・Array・Eraseを業務で徹底解説
この記事の内容
「VBAの配列で初期化がうまくいかない」「ReDimとEraseの違いが分からない」——Excelマクロを書き始めると、こうした壁に早い段階でぶつかります。配列(はいれつ)は、VBAで業務自動化を本格的に進めるときに避けて通れない概念であり、特に「初期化」の操作は複数の方法があって混乱しやすいポイントです。
この記事では、VBA配列の初期化方法をErase・Array関数・ReDim・ReDim Preserveの4種類すべてについて、動作の違いから実際のコード例、業務での使いどころまで体系的に解説します。「配列は何となく分かるが、初期化で詰まる」という方から、「配列を使って業務Excelをもっと速くしたい」という方まで、読み終わると自信を持って配列を扱えるようになります。
この記事で分かることをまとめると、次のとおりです。
01 VBA BASICS 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ヶ月分であれば固定長、データベースから取得するレコード数が毎回変わるなら可変長が適切です。次のセクションで、それぞれの宣言方法を具体的に解説します。
02 ARRAY DECLARATION 固定長配列と可変長配列の宣言方法 宣言の構文・インデックスの基本・スコープの考え方を押さえる
配列を使うには、まず「宣言」が必要です。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()関数を使う方が安全なコーディングスタイルです。
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
で次回に備える
03 ERASE 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
可変長配列(Dim arr() As String)にEraseを使うと、配列のメモリが完全に解放されます。この後arr(0)にアクセスすると「添え字が有効範囲にありません(エラー番号9)」が発生します。Erase後は必ずReDimで再初期化してから使ってください。このパターンはVBAのバグで最もよく見かける原因の一つです。
3-3. データ型別のErase後のデフォルト値
| データ型 | Erase後の値 | 用途の目安 |
|---|---|---|
| Integer / Long / Double | 0(ゼロ) | 数値集計用配列のリセット |
| String | ""(空文字) | 氏名・コード等の文字列配列のリセット |
| Boolean | False | フラグ管理配列のリセット |
| Date | 1899/12/30 | 日付配列のリセット(ほぼ使わない) |
| Object | Nothing | オブジェクト参照配列の解放 |
| Variant | Empty | 型不定の配列のリセット |
04 ARRAY FUNCTION 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
配列をLoop内でのマッチングに使うだけでなく、Join関数と組み合わせると「1月,2月,...,12月」のようなカンマ区切り文字列に変換できます。また「Filter(配列, 検索文字)」関数と組み合わせると、配列から条件に合う要素だけを抽出した新しい配列を生成できます。これらの組み合わせが業務マクロでよく使われる実践パターンです。
05 REDIM 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
06 REDIM PRESERVE 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次元目で表現する
2次元配列arr(行, 列)に対して「ReDim Preserve arr(新しい行数, 列数)」と書くとエラーになります。Preserveで変更できるのは最後の次元(列方向)のみです。行方向に動的に追加したい場合は、配列の定義を転置して「arr(列インデックス, 行インデックス)」の形にするか、先に行数の上限を大きめにReDimしておいて最後にPreserveで縮小する設計を使ってください。
全データリセット
要素数変更
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
07 MULTIDIMENSIONAL 多次元配列の初期化と業務活用 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
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が発生します。
一括読み込み
Range.Value→
2次元配列化
処理実行
ループ・フィルタ
集計・変換
格納
別の配列に
結果を書く
配列→Range.Value
で1回書き出し
この「読み込み→配列処理→書き出し」のパターンを使うと、セルへのアクセス回数が「全件数×2(読み書き)」から「2回(一括読み込み・一括書き出し各1回)」に激減します。1000件なら2000回→2回、10000件なら20000回→2回です。Excelマクロが遅くて困っている場合、原因の多くがこのセルアクセス過多にあり、配列への切り替えで劇的に改善されます。
08 ERROR HANDLING よくあるエラーと対処法 配列関連のエラー番号と根本原因・修正方法を網羅
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
「この配列にデータは入っているか」を確認したい場合、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
09 CLAUDE CODE Claude CodeでVBAコードを自動生成する AI活用でVBAの壁を越える:非エンジニアでもマクロが書ける
ここまで読んで「VBAの配列は理解できてきたが、自分でゼロからコードを書くのはまだハードルが高い」と感じている方もいるかもしれません。そこで弊社が実践しているのが、Claude Codeを活用したVBAコードの自動生成です。配列処理のような少し複雑なコードも、業務の要件を日本語で説明するだけでClaude Codeが正確に書いてくれます。
Claude Codeはターミナル(コマンドライン)上で動くAIエージェントですが、VBAのコード生成においては「自然な日本語で業務要件を説明→配列を使った最適なVBAコードを生成」という形で活用できます。ReDimを使うべきかReDim Preserveを使うべきか、2次元配列が適切かどうか、という設計判断まで含めてAIが考えてくれます。
9-1. Claude Codeへの効果的な指示の書き方
VBAの配列を使ったコード生成をClaude Codeに依頼する際のポイントは、業務のゴールと「データの性質」をセットで伝えることです。件数が毎回変わるのか固定なのか、2次元データなのか1次元なのか——こうした情報を伝えることで、Claude Codeが固定長か可変長か、ReDimかReDim Preserveかを適切に判断してコードを書いてくれます。
' 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
コードが生成されたら「なぜReDimではなくDictionaryを使ったのか」「可変長配列を選んだ理由は?」と追加で聞くことができます。Claude Codeは設計判断の根拠も日本語で説明してくれるので、コードを読むだけでなく、なぜそう書くのかの理解も同時に深まります。
非エンジニアの経営者・管理職の方がClaude Codeを活用してVBAを自動化するステップを整理すると、「業務課題の定義(何が面倒なのか)→Claude Codeへの日本語指示→生成されたコードを社内Excelに貼り付けて実行→動作確認→改善点があれば追加指示」というサイクルになります。プログラミングの知識がなくても、業務の要件を言語化できれば自動化が実現できる時代になっています。弊社(株式会社GENAI)では、こうしたClaude Codeを活用した業務自動化の設計・実装支援を「AI鬼管理」として提供しています。
10 CONCLUSION まとめ VBA配列の初期化を完全に使いこなすために
この記事では、VBA配列の初期化方法を4つの手段——Erase・Array関数・ReDim・ReDim Preserve——に分けて完全解説しました。最後にポイントを振り返ります。
配列の初期化を正確に理解することで、VBAコードの品質と処理速度が格段に向上します。「なんとなく動いているが、時々エラーが出る」という状況は、ほとんどの場合がEraseとReDimの使い分けの理解不足か、固定長・可変長の混同から来ています。この記事で整理した4つの初期化方法をマスターすれば、そうした問題から解放されます。
VBAのコードを自分で書くのが難しい場合は、Claude Codeに業務の要件を日本語で説明するだけで、配列を使った最適なコードを自動生成できます。「VBAは難しい」ではなく、「AIをうまく使えば非エンジニアでも業務自動化ができる」という時代になっています。弊社のAI鬼管理では、こうした自動化設計の無料相談を承っています。
VBAの業務自動化を、AI鬼管理が一緒に設計します
「Excelマクロで業務を自動化したいが、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コードを生成してくれます。件数が変動するか固定かを伝えると、固定長・可変長の選択も自動判断されます。
Claude Codeで業務自動化を90日で叩き込む
経営者向けの伴走型パーソナルトレーニング
Claude Code を業務に落とし込む
専門研修コース一覧
受講者本人の業務を題材に、「使いこなせる」状態になるまで伴走する研修プログラム。1対1特化型・ハンズオン・法人講座の3コースを展開中。業務特化・実装まで踏み込むタイプのClaude Code研修です。
研修コース一覧を見る →AI鬼管理へのお問い合わせ
この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。




