VBAで自動化 VBAテクニック集 VBA一覧 呼び出し処理 文法・構文

【VBA】「プロシージャが大きすぎます」エラーの回避方法(プロシージャの分割)

Excel VBAでコードを作成していると、「プロシージャが大きすぎます」というエラーが発生することがあります。
このエラーは、1つのプロシージャが64 KBを超えると発生し、コードの実行ができなくなります。

この記事では、「プロシージャが大きすぎます」エラーの原因と、その回避策としてのプロシージャ分割方法について解説します。

「プロシージャが大きすぎます」エラーとは?

VBAでは、1つのプロシージャ(SubまたはFunction)のコードサイズが64 KBを超えると、コンパイルエラーが発生します

【エラーメッセージ】

Compile error: Procedure too large

【エラーの発生原因】

コードの行数が多すぎる(数千行を超える)
データ処理のループが複雑で無駄が多い
一つのプロシージャ内に複数の異なる処理が立っている

📌解決策:コードを複数のプロシージャ(Sub や Function)に分割すること!

「プロシージャが大きすぎます」エラーの回避方法(プロシージャの分割)

【VBA】プロシージャの限界とその回避策

・処理ごとにサブに分割

1つのプロシージャでデータ入力・計算・書式設定・ファイル保存などの処理をまとめている場合は、それぞれの処理を独立したサブに分割します

【修正前:長すぎるプロシージャ】

Sub ProcessData()

Dim ws As Worksheet
Dim i As Integer
Set ws = ThisWorkbook.Sheets("Sheet1")

' データ入力
For i = 1 To 10000

ws.Cells(i, 1).Value = "データ " & i

Next i

' 書式設定
ws.Range("A1:A10000").Font.Bold = True

' 合計計算
ws.Cells(10001, 1).Formula = "=SUM(A1:A10000)"

' メッセージ表示
MsgBox "処理完了!"

End Sub

📌問題点

  • 1つのプロシージャが長くなりすぎている
  • 各処理(データ入力・書式設定・合計計算・メッセージ表示)が一緒に処理される

【修正後:適切に分割】

Sub ProcessData()

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")

InputData ws
FormatCells ws
CalculateTotal ws
ShowCompletionMessage

End Sub

' データ入力処理
Sub InputData(ws As Worksheet)

Dim i As Integer
For i = 1 To 10000

ws.Cells(i, 1).Value = "データ " & i

Next i

End Sub

' 書式設定処理
Sub FormatCells(ws As Worksheet)

ws.Range("A1:A10000").Font.Bold = True

End Sub

' 合計計算処理
Sub CalculateTotal(ws As Worksheet)

ws.Cells(10001, 1).Formula = "=SUM(A1:A10000)"

End Sub

' メッセージ表示処理
Sub ShowCompletionMessage()

MsgBox "処理完了!"

End Sub

1つのプロシージャに1つの目的のみを持たせることで、コードの可読性が向上!
修正が必要な場合も、該当のサブのみを変更すればよい!

・ループ処理を関数に選択

大量のデータを処理するループが1 つのプロシージャに直接書かれていると、コードが肥大化します

【修正前:長いループ処理】

Sub ProcessData()

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")

Dim i As Integer
For i = 1 To 10000

ws.Cells(i, 1).Value = "データ " & i

Next i

End Sub

【修正後:ループを関数に選択】

Sub ProcessData()

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")

FillData ws, 1, 10000

End Sub

Sub FillData(ws As Worksheet, startRow As Integer, endRow As Integer)

Dim i As Integer
For i = startRow To endRow

ws.Cells(i, 1).Value = "データ " & i

Next i

End Sub

データの範囲を指定して処理できるため、汎用性が向上!
他のプロシージャでもFillData再利用可能!

・長い条件分岐を整理する

もし文やSelect Caseの分裂が多くなる場合、コードが肥大化し、可読性が低下します。

【修正前:長い場合の文】

Sub ProcessData(value As Integer)

If value = 1 Then

MsgBox "処理Aを実行"

ElseIf value = 2 Then

MsgBox "処理Bを実行"

ElseIf value = 3 Then

MsgBox "処理Cを実行"

Else

MsgBox "無効な値です"

End If

End Sub

【修正後:Select Caseに整理】

Sub ProcessData(value As Integer)

Select Case value

Case 1: ExecuteA
Case 2: ExecuteB
Case 3: ExecuteC
Case Else: MsgBox "無効な値です"

End Select

End Sub

Sub ExecuteA()

MsgBox "処理Aを実行"

End Sub

Sub ExecuteB()

MsgBox "処理Bを実行"

End Sub

Sub ExecuteC()

MsgBox "処理Cを実行"

End Sub

各処理を独立したサブに決めることで、コードがシンプルに!
新しい処理を追加する際も、影響範囲が最小限に!

まとめ

回避策方法メリット
処理ごとに分割Sub ProcessData → Sub InputData, Sub FormatCellsコードが整理され、可読性が向上
ループを関数に選択Sub FillData(ws, startRow, endRow)ループ処理を再利用可能
長い条件分岐を整理Select Caseを使い、処理を独立したサブに選択メンテナンスしやすくなる

💡 VBA の「プロシージャが大きすぎます」エラーを回避するためには、
1つのプロシージャに1つの役割を持たせる
ループや分割を分割し、シンプルにする
汎用的な処理は関数にする

【VBA】プロシージャを分割するメリットと実践方法

    -VBAで自動化, VBAテクニック集, VBA一覧, 呼び出し処理, 文法・構文