エラーの内容と発生タイミング
VBAマクロの作業中——5万行をループ処理したり、売上を集計したり、カウンターが33,000を超えたあたりで——Excelが突然このエラーを表示します:
Run-time error '6': Overflow
マクロは完全に停止します。VBAエディターが開き、1行が黄色くハイライトされます。その行こそ、VBAが数値を小さすぎる器に詰め込もうとした場所です。
VBAの変数にはそれぞれ固定の数値範囲があります。その範囲を超える値を代入するとOverflowが発生します。十中八九、原因はLongが必要な処理にInteger変数を使っていることです。
根本原因
VBAの各データ型が保持できる値には決まった範囲があります:
- Integer:–32,768 〜 32,767
- Long:–2,147,483,648 〜 2,147,483,647
- Single:±3.4 × 1038(精度に制限あり)
- Double:±1.8 × 10308
- Byte:0 〜 255
- Currency:–922,337,203,685,477.5808 〜 922,337,203,685,477.5807
Integerの上限である32,767という数字が落とし穴です。Excel 2007以降、Excelは最大1,048,576行をサポートしています。行カウンターをIntegerで宣言すると、32,768行目に達した瞬間にVBAがクラッシュします。シートには100万行の可能性があるのに、カウンターは32,000程度で頭打ちになるのです。
手順1 — 問題の行を特定する
ダイアログが表示されたとき、終了をクリックしないでください。代わりにデバッグをクリックします。VBAエディターが開き、エラーが発生した行が黄色くハイライトされます——オーバーフローが起きた正確な場所です。
主なパターンは3つあります:
' カウンターをIntegerで宣言しているが、シートの行数が32,767を超えている
Dim i As Integer
For i = 1 To 100000 ' 32,768でクラッシュ
' ...
Next i
' 演算結果がIntegerの範囲を超えている
Dim result As Integer
result = 200 * 200 ' 40,000 > 32,767 → Overflow
' 最終使用行が50,000以上だが、Integerに格納しようとしている
Dim rowCount As Integer
rowCount = Cells(Rows.Count, 1).End(xlUp).Row
手順2 — オーバーフローしている変数を特定する
ハイライトされた行の変数にマウスをホバーすると、ツールチップに現在の値が表示されます。それでも不明な場合は、クラッシュする行の直前にDebug.Printを挿入します:
Debug.Print "Value before overflow: " & yourVariable
Ctrl+Gでイミディエイトウィンドウを開き、マクロを再実行します。出力された値から、エラーを引き起こした数値を正確に把握できます。
手順3 — データ型を修正する
IntegerをLongに変更する
この変更だけでOverflowエラーの約80%が解決します。行数をカウントしたり、IDを格納したり、32,767を超える可能性のある合計を蓄積する変数はすべてLongにすべきです:
' 修正前 — 32,767行を超えるとクラッシュ
Dim i As Integer
For i = 1 To lastRow
' 行を処理
Next i
' 修正後 — 1,048,576行すべてを問題なく処理
Dim i As Long
For i = 1 To lastRow
' 行を処理
Next i
オーバーフローする演算を修正する
ここには見落としやすい落とし穴があります。VBAは演算を代入先の型ではなく、オペランドの型に基づいて評価します。result As Longと宣言しても、Integerリテラル同士を掛け合わせていれば意味がありません。代入が行われる前に式がオーバーフローしてしまうのです。
' 落とし穴:代入前に式がオーバーフローする
Dim result As Long
result = 200 * 200 ' 200と200はInteger → Integer * Integer → Overflow
' 修正方法1:Longリテラルサフィックスを使う
result = 200& * 200
' 修正方法2:明示的な変換
result = CLng(200) * 200
' 修正方法3:オペランドをLongとして宣言する
Dim a As Long, b As Long
a = 200 : b = 200
result = a * b
Single/Doubleのオーバーフローを修正する
非常に大きな数値や科学計算ではLongの上限(約21億)を超えることがあります。その場合はDoubleに切り替えます:
Dim bigNum As Double
bigNum = 3000000000# * 1500 ' # サフィックスでDoubleリテラルを強制
Byteのオーバーフローを修正する
Byteは0〜255しか保持できません。Byte変数にエラーコードとして–1を返すと即座にOverflowが発生します:
' 修正前
Dim status As Byte
status = someFunction() ' エラー時に-1を返す → Overflow
' 修正後
Dim status As Integer
修正済みコードの完全な例
現実的なシナリオ:使用されているすべての行の列を合計する処理です。壊れたバージョンは小さいテストシートでは正常に動作しますが、データが32,767行を超えると本番環境で突然クラッシュします。
' 壊れたバージョン — 32,767行を超えるシートでオーバーフロー
Sub ProcessData_Broken()
Dim i As Integer
Dim total As Integer
Dim lastRow As Integer
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
total = total + Cells(i, 2).Value
Next i
MsgBox "Total: " & total
End Sub
' 修正済みバージョン
Sub ProcessData_Fixed()
Dim i As Long
Dim total As Double ' 合計が大きくなる可能性があるためDouble
Dim lastRow As Long
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
total = total + CDbl(Cells(i, 2).Value)
Next i
MsgBox "Total: " & total
End Sub
修正を確認する
- F5キーを押して実行します。エラーダイアログが表示されなければオーバーフローは解消されています。
- 大きな範囲が正しく処理されているか確認するため、行数を出力します:
Debug.Print "Processing " & lastRow & " rows" - データが大きくなる可能性がある場合は、32,767行を超えるシートでテストしてください。
- F8キーでコードをステップ実行し、ローカルウィンドウ(表示 → ローカルウィンドウ)で各変数が型の上限に近づいていないか監視します。
今後のための防御的な習慣
- IntegerではなくLongをデフォルトにする:
Longは4バイト、Integerは2バイトですが、現代のプロセッサは32ビット整数をネイティブに処理するため、実用上の性能差はありません。Integerの範囲制限をなくせる一方、デメリットは何もありません。 - Option Explicitを使う:すべてのモジュールの先頭に
Option Explicitを記述します。変数の宣言を強制することで、型の選択ミスを実行時エラーになる前に発見できます。 - 数値リテラルに注意する:VBAでは
200はデフォルトでIntegerとして扱われます。型サフィックスで明示してください:Longは200&、Doubleは200#。 - 外部データを検証する:セルの値を変数に代入する場合は、まず
IsNumeric()で確認し、型付き変数に格納する前に値の範囲が妥当かチェックしてください。

