Excelマクロを実行したとき、「実行時エラー’6′: オーバーフローしました。」というダイアログが表示されて処理が止まってしまう——そんな経験はないでしょうか。
このエラーは、変数に格納できる値の上限を超えた場合や、計算の途中で型の許容範囲をオーバーした場合に発生します。一見するとコードに誤りが見当たらないように見えるため、原因の特定に時間がかかることも珍しくありません。
本記事では、Microsoft公式ドキュメント(Office VBA リファレンス)をはじめとする正確な情報をもとに、エラー6の仕組み・発生パターン・具体的な修正方法を網羅的に解説します。変数の型の選び方や、型変換関数(CLng・CDbl など)の正しい使い方も詳しく説明しますので、初心者から中級者まで役立てていただける内容となっています。
目次
- 実行時エラー’6’(オーバーフロー)とは何か
- VBAの数値型と格納できる値の範囲一覧
- 原因1:変数の型の上限を超える値を直接代入した
- 原因2:右辺の計算結果が型の上限を超えた(暗黙の型変換の落とし穴)
- 原因3:Integer型でループカウンタや最終行を取得した
- 原因4:同じ型同士の演算結果がその型の上限を超えた
- 原因5:セルの書式設定が原因でオーバーフローが発生した
- 原因6:プロパティへの割り当て値が上限を超えた
- 型変換関数を使った解決方法まとめ
- エラー箇所の特定方法(デバッグ手順)
- エラー6を未然に防ぐコーディング習慣
- 解決方法チェックリスト
- よくある質問(FAQ)
1. 実行時エラー’6’(オーバーフロー)とは何か
実行時エラー’6’「オーバーフローしました。」は、変数やプロパティに割り当てようとした値が、その型に許可されている値の範囲を超えたときに発生するエラーです。Microsoftの公式VBAリファレンスでも、「割り当て先の制限を超える割り当てを試行したときにオーバーフローが発生します。」と定義されています。
「オーバーフロー」という言葉を直訳すると「あふれる」です。変数という名の入れ物に、その容量を超えた水(データ)を注ごうとしてあふれてしまうイメージで捉えると理解しやすいでしょう。
発生パターンは大きく分けると以下の3つです。
- 割り当て・計算・データ型変換の結果が大きすぎて、変数型に許可されている値の範囲内で表すことができない場合
- プロパティへの割り当てがプロパティに割り当てることができる最大値を超えている場合
- 計算で使用した数値が暗黙のうちに整数に強制変換され、その結果が整数の上限を超えた場合
2. VBAの数値型と格納できる値の範囲一覧
オーバーフローを理解・防止するためには、VBAで使える数値型の範囲を把握しておくことが不可欠です。以下に主要な数値型をまとめます。
| 型名 | 格納できる値の範囲 | メモリ | 主な用途 |
|---|---|---|---|
| Byte | 0 ~ 255 | 1バイト | 小さい正の整数 |
| Integer | -32,768 ~ 32,767 | 2バイト | 小さい整数(多用は要注意) |
| Long | -2,147,483,648 ~ 2,147,483,647 | 4バイト | 行番号・大きな整数 |
| Single | 約 ±3.4×1038(単精度浮動小数点) | 4バイト | 小数を含む計算(精度は低め) |
| Double | 約 ±1.8×10308(倍精度浮動小数点) | 8バイト | 精度が必要な小数計算 |
| Currency | -922,337,203,685,477.5808 ~ 922,337,203,685,477.5807 | 8バイト | 金額・財務計算 |
| Decimal | ±79,228,162,514,264,337,593,543,950,335(小数点なし) | 14バイト | 最大精度の数値計算 |
| Variant | 数値・文字列・日付など何でも格納可能 | 16バイト以上 | 汎用(エラー6は発生しない) |
重要なのは、エラー6が発生しうるのは数値型(Byte・Integer・Long・Single・Double・Currency・Decimal)に限られる点です。Boolean、Object、Variantはエラー6を引き起こしません。Booleanは0以下をFalse、1以上をTrueと解釈するため、値の範囲判定の仕組みが他の型と異なります。
また、現代のVBA開発ではIntegerではなくLongを使うことが推奨されています。 理由は後述しますが、Excelの最終行数(1,048,576行)がIntegerの上限(32,767)を大幅に超えているためです。
3. 原因1:変数の型の上限を超える値を直接代入した
最も基本的なオーバーフローのパターンです。Integer型の変数に32,767を超える値を代入しようとしたとき、エラーが発生します。
' NG例:Integer型に上限を超える値を代入
Sub Sample_NG1()
Dim N As Integer
N = 40000 ' Integerの上限(32,767)を超えるため エラー6発生
End Sub
解決方法:より大きな型に変更する
格納しようとしている値の範囲に合った、より大きい型に変更してください。整数値であればLong型、小数を含む場合はDouble型が一般的な選択肢です。
' OK例:Long型に変更する
Sub Sample_OK1()
Dim N As Long
N = 40000 ' Long型の範囲(約±21億)内なので問題なし
End Sub
4. 原因2:右辺の計算結果が型の上限を超えた(暗黙の型変換の落とし穴)
これはエラー6の中でも最も気づきにくいパターンです。左辺の変数をLong型で宣言しているにもかかわらず、エラーが発生するケースです。
Microsoftの公式ドキュメントでも以下のコードがエラーになる例として示されています。
' NG例:Long型の変数に代入しているのにエラー6が発生する
Sub Sample_NG2()
Dim x As Long
x = 2000 * 365 ' エラー6発生!なぜ?
End Sub
2000 * 365 = 730,000 です。Long型の範囲(約±21億)には十分に収まります。それなのになぜエラーになるのでしょうか。
なぜエラーになるのか:VBAの暗黙型変換ルール
VBAでは、コードに直接書かれた整数リテラルは格納可能な最小サイズの型(Integer型)として扱われます。2000も365も、どちらもInteger型の範囲内に収まります。そのため、VBAはこの乗算を「Integer × Integer」と解釈し、計算結果を一時的にInteger型の変数へ格納しようとします。しかし結果の730,000はIntegerの上限(32,767)を大幅に超えるため、左辺のLong型に値が渡る前の時点でオーバーフローが起きます。
解決方法:CLng関数などで型変換してから計算する
Microsoftの公式ドキュメントでは、一方の数値をCLng関数でLong型に変換してから掛け算することを推奨しています。
' OK例1:CLng関数でLong型に変換してから計算(Microsoft公式推奨)
Sub Sample_OK2a()
Dim x As Long
x = CLng(2000) * 365 ' 片方をLong型に変換すれば結果もLong型になる
End Sub
' OK例2:Long型リテラルとして&を末尾に付ける
Sub Sample_OK2b()
Dim x As Long
x = 2000& * 365 ' 2000をLong型リテラルとして指定
End Sub
' NG例:計算結果をCLngしても意味がない
Sub Sample_NG2b()
Dim x As Long
x = CLng(2000 * 365) ' ← 計算の時点でInteger×Integerのためエラー
End Sub
重要なのは、CLng関数を計算結果に対してかけても解決しないという点です。計算が実行される時点で既にInteger同士の演算が行われるため、変換前にオーバーフローが起きてしまいます。演算を行う前に少なくとも一方の値をCLngなどで変換する必要があります。
5. 原因3:Integer型でループカウンタや最終行を取得した
実務でよく見られるパターンです。特にExcel VBAでは行数の取得や繰り返し処理に変数を使うことが多いため、Integer型の上限(32,767)に引っかかりやすいです。
Excelのxlsx形式における最終行は1,048,576行です。xls形式でも65,536行あります。どちらもIntegerの上限(32,767)をはるかに超えています。
5-1. Integer型で最終行を取得するパターン
' NG例:Integer型で最終行を取得(データが32,768行以上あるとエラー)
Sub Sample_NG3a()
Dim rowEnd As Integer
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row ' データが多いとエラー6発生
End Sub
' OK例:Long型で最終行を取得する
Sub Sample_OK3a()
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row ' 問題なし
End Sub
5-2. Integer型でFor〜Nextループのカウンタを使うパターン
' NG例:カウンタがInteger型でループが32,768回以上になるとエラー
Sub Sample_NG3b()
Dim i As Integer
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To rowEnd ' rowEndが32,767を超えると i の代入でエラー6
Cells(i, 2).Value = Cells(i, 1).Value * 2
Next i
End Sub
' OK例:カウンタもLong型に変更する
Sub Sample_OK3b()
Dim i As Long
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To rowEnd ' Long型なので大量行でも問題なし
Cells(i, 2).Value = Cells(i, 1).Value * 2
Next i
End Sub
5-3. Do〜Loopで無限ループになるパターン
Do〜Loopを使用するとき、ループの継続条件の設定を誤ってループから抜けられない状態になった場合もエラー6が発生します。カウンタがInteger型の上限まで達するためです。
' NG例:ループ条件が誤っていて無限ループになりInteger上限でエラー
Sub Sample_NG3c()
Dim cnt As Integer
cnt = 10
Do While Cells(cnt, 2) = "" ' B列に値がある行が存在しない場合、永久にループ
cnt = cnt + 1
Loop
End Sub
' OK例:Long型に変更しつつ、上限チェックも追加する
Sub Sample_OK3c()
Dim cnt As Long
cnt = 10
Do While Cells(cnt, 2) = "" And cnt <= Rows.Count
cnt = cnt + 1
Loop
If cnt > Rows.Count Then
MsgBox "対象データが見つかりませんでした。"
End If
End Sub
6. 原因4:同じ型同士の演算結果がその型の上限を超えた
同じ型同士で演算すると、演算結果も同じ型で返されます。たとえばByte型同士の足し算の結果もByte型として扱われるため、255を超えた瞬間にオーバーフローします。
' NG例:Byte型同士の足し算が256になってエラー
Sub Sample_NG4()
Dim b1 As Byte
Dim b2 As Byte
b1 = 255
b2 = 1
Dim i As Integer
i = b1 + b2 ' Byte + Byte = Byte型として計算 → 256はByteの上限超え → エラー6
End Sub
' OK例:CInt関数でInteger型に変換してから演算する
Sub Sample_OK4()
Dim b1 As Byte
Dim b2 As Byte
b1 = 255
b2 = 1
Dim i As Integer
i = CInt(b1) + CInt(b2) ' Integer同士の加算になるのでOK(片方だけの変換でも可)
' i = CInt(b1) + b2 ← 片方だけ変換でも結果はIntegerになるのでOK
End Sub
7. 原因5:セルの書式設定が原因でオーバーフローが発生した
これは比較的珍しいケースですが、実務でハマりやすいパターンです。セルの書式設定が不正な状態になっていると、Variant型で受け取ろうとしてもエラー6が発生することがあります。
現象の例
あるセルの値をVariant型の変数に代入しようとしただけでエラー6が出る場合、そのセルの書式が壊れている可能性があります。
' Variant型なのにエラー6が出る場合はセルの書式を確認
Sub Sample_CellFormat()
Dim v As Variant
v = Range("B3").Value ' B3の書式が壊れているとエラー6
End Sub
解決方法:セルの書式を「標準」または「数値」に変更する
- 該当セルを選択し、右クリック→「セルの書式設定」を開く
- 「表示形式」タブで「標準」または「数値」を選択してOK
- 書式が正常なセルからコピー貼り付けを行う方法も有効
- シートに保護がかかっている場合は先に保護を解除する
8. 原因6:プロパティへの割り当て値が上限を超えた
Microsoftの公式ドキュメントには、「プロパティへの割り当てがプロパティに割り当てることができる最大値を超えている」場合もエラー6が発生すると記載されています。たとえば、特定のコントロールやオブジェクトのプロパティに対して、設定できる値の範囲を超えた値をセットしようとした場合が該当します。
' 例:スクロールバーのMaxプロパティに上限を超える値を設定した場合
Sub Sample_PropertyOverflow()
' UserForm上のScrollBar1のMaxは32767まで(Integer型の上限)
' UserForm1.ScrollBar1.Max = 100000 ' ← 上限を超えるためエラー6発生の可能性
' 正しい範囲内で設定する
UserForm1.ScrollBar1.Max = 32767
End Sub
この場合の解決方法は、プロパティに設定できる上限値を確認し、その範囲内に収まるよう値を調整することです。
9. 型変換関数を使った解決方法まとめ
エラー6の解決には、VBAが提供する型変換関数を活用することが重要です。主要な変換関数と使用シーンをまとめます。
| 関数名 | 変換先の型 | 使用例 | 使用シーン |
|---|---|---|---|
| CInt() | Integer | CInt(3.7) → 4 | 小さな整数値への変換 |
| CLng() | Long | CLng(2000) * 365 | 大きな整数の計算前に使用 |
| CDbl() | Double | CDbl(x) / CDbl(y) | 小数を含む除算・精度が必要な計算 |
| CSng() | Single | CSng(val) | 単精度浮動小数点への変換 |
| CCur() | Currency | CCur(price) | 金額・財務計算 |
| CDec() | Decimal | CDec(bigNum) | 最大精度が必要な超大数値 |
型変換を使ったコード例(実践パターン)
' 大きな数の掛け算にはCLng/CDblを使う
Sub ConversionExamples()
Dim result1 As Long
Dim result2 As Double
' 整数の大きな計算 → CLng
result1 = CLng(500) * CLng(1000) ' 500,000 → Long型で正常
Debug.Print "result1 = " & result1
' 小数を含む計算 → CDbl
result2 = CDbl(355) / CDbl(113) ' 円周率の近似値
Debug.Print "result2 = " & result2
' Long型リテラル(&)を使った代替方法
Dim result3 As Long
result3 = 500& * 1000& ' &を付けるとLong型リテラルになる
Debug.Print "result3 = " & result3
End Sub
10. エラー箇所の特定方法(デバッグ手順)
エラー6が発生したとき、ダイアログの「デバッグ」ボタンを押すことで、VBE上でエラーが発生した行が黄色くハイライト表示されます。これがデバッグの第一歩です。
10-1. デバッグボタンでエラー行を特定する
エラーダイアログが表示されたら「デバッグ」ボタンをクリックしてください。VBE(Visual Basic Editor)が開き、エラーが発生している行が黄色くハイライトされます。どの変数や演算でオーバーフローが起きているかを、その行で確認できます。
10-2. イミディエイトウィンドウで変数の値を確認する
デバッグモードで停止中に、VBEの「表示」→「イミディエイト ウィンドウ」(Ctrl+G)を開き、変数の実際の値を確認できます。
' イミディエイトウィンドウでの確認コマンド例
? rowEnd ' rowEnd変数の値を表示
? TypeName(rowEnd) ' rowEndの型名を確認
? Cells(Rows.Count, 1).End(xlUp).Row ' 実際の最終行番号を確認
10-3. ブレークポイントとステップ実行を使う
VBEで行番号の左側をクリックしてブレークポイントを設定し、F8キーで1行ずつ実行することで、どの計算でオーバーフローが起きているかを正確に特定できます。
' デバッグ時に型と値の範囲を確認するヘルパーマクロ
Sub CheckVariableType()
Dim n1 As Integer
Dim n2 As Long
n1 = 30000
n2 = 30000
Debug.Print "n1 TypeName: " & TypeName(n1) & " / Value: " & n1
Debug.Print "n2 TypeName: " & TypeName(n2) & " / Value: " & n2
Debug.Print "Integer Max: " & (2 ^ 15 - 1) ' = 32767
Debug.Print "Long Max: " & (2 ^ 31 - 1) ' = 2147483647
End Sub
11. エラー6を未然に防ぐコーディング習慣
11-1. 整数型は原則Long型を使う
現代のExcel VBA開発において、整数を扱う変数はIntegerではなくLongを使うことが推奨されています。Excelのシート行数がIntegerの上限をはるかに超えているためです。メモリ消費の差(2バイト vs 4バイト)は現代のPCでは無視できるレベルです。
' 推奨パターン:整数はすべてLong型で宣言する
Sub GoodPractice()
Dim i As Long ' ループカウンタ
Dim rowEnd As Long ' 最終行
Dim total As Long ' 合計値
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To rowEnd
total = total + Cells(i, 1).Value
Next i
MsgBox "合計: " & total
End Sub
11-2. Option Explicitで変数宣言を強制する
すべてのモジュール先頭に Option Explicit を記述することで、型のない変数(Variant型として暗黙的に処理される)の使用を防ぎ、意図しない型での演算が発生しにくくなります。
Option Explicit ' モジュール先頭に必ず記述
Sub Sample()
' Dim宣言なしで変数を使おうとするとコンパイルエラーが出る
Dim i As Long
' ...
End Sub
Option ExplicitはVBEの「ツール」→「オプション」→「変数の宣言を強制する」にチェックを入れることで、新規モジュールに自動的に追加されるようになります。
11-3. 演算前に型変換を明示的に行う
整数リテラルを使った掛け算や計算式には、CLng・CDblなどを積極的に使い、意図した型で演算されることを明示しましょう。
' 計算には明示的な型変換を使う習慣を持つ
Sub SafeCalculation()
Dim days As Long
Dim population As Long
' 大きな数の積算はCLngで型を明示
days = CLng(365) * CLng(100) ' 36500日(問題なし)
population = CLng(10000) * CLng(7000) ' 7億(Long型の範囲内)
Debug.Print "days = " & days
Debug.Print "population = " & population
End Sub
11-4. セルから読み込む値はVariantまたはLong/Doubleで受け取る
セルの値が何行目まで増えるかわからない場合や、どんな数値が入るか不明な場合は、VariantまたはLong・Doubleで受け取るのが安全です。
' セル値の読み込みはVariantまたはLong/Doubleが安全
Sub SafeCellRead()
Dim cellVal As Variant
cellVal = Range("A1").Value ' セルの値は型不明のためVariantが安全
' 数値として使う場合はCLng/CDblで明示変換
If IsNumeric(cellVal) Then
Dim num As Long
num = CLng(cellVal)
Debug.Print num
End If
End Sub
12. 解決方法チェックリスト
エラー6が発生したときに上から順番に確認してください。
- エラーダイアログの「デバッグ」ボタンを押してエラー発生行を特定する
- エラー行の変数の型を確認し、Integer型を使っている場合はLong型に変更する
- 右辺の計算式でInteger×Integerなどの暗黙型演算が発生していないか確認する
- CLng・CDblなどの型変換関数を計算前の数値に適用する(計算後への適用は無効)
- For〜NextやDo〜Loopのカウンタ変数がInteger型になっていないか確認する
- 最終行取得(
.End(xlUp).Row)の格納先変数をLong型にする - Do〜Loopの継続条件が正しく設定されており、無限ループにならないか確認する
- Byte型同士など同型の演算で上限を超えていないか確認し、CInt/CLngで変換する
- エラーが特定のセルで発生する場合はそのセルの書式設定を「標準」に変更する
- UserFormコントロールのプロパティ(Max値など)が許容範囲内か確認する
- すべてのモジュール先頭にOption Explicitを追加して変数の型宣言を徹底する
13. よくある質問(FAQ)
Q1. Long型に変えたのにまだエラー6が出ます。なぜですか?
左辺をLong型にしても、右辺の演算が依然としてInteger型で行われている可能性があります。演算に使うリテラルやInteger型の変数の少なくとも一方をCLng関数で変換してください。計算結果への変換(CLng(a * b)という書き方)は無効です。計算前の変数・値への変換が必要です。
Q2. Variant型を使えばエラー6は完全に防げますか?
Variantは多くのケースでオーバーフローを回避できますが、セルの書式設定が壊れている場合など、Variant型でもエラー6が発生することがあります。また、Variant型はメモリ消費が大きく処理速度も低下するため、型が明確な場合はLong・Doubleなど適切な型を使うほうが良い実装です。
Q3. なぜVBAでは整数の計算をInteger型で自動処理するのですか?
VBAは整数リテラルを「格納可能な最小サイズの型」として扱うよう設計されています。これはメモリ効率のための仕様ですが、現代のPCではメモリの差は無視できるレベルです。最初からLong型を使う習慣を持つことで、この問題を避けられます。
Q4. Integer型を使い続けても問題ない場合はありますか?
格納する値が確実に-32,768〜32,767の範囲に収まることが保証されており、かつ計算結果もその範囲を超えない場合は理論上問題ありません。しかし、将来的なデータ増加やコード改修を考えると、最初からLong型を使うほうがリスクが低く、保守性も高まります。
Q5. 小数の計算でエラー6が出ました。どう対処しますか?
Single型やDouble型での計算でオーバーフローが起きる場合は、より大きな範囲を持つDouble型(約±1.8×10308)またはCurrency型(金額計算向け)への変更を検討してください。それでも不足する超大数値にはCDec関数でDecimal型に変換して使います。
まとめ
Excelマクロの実行時エラー’6’(オーバーフロー)は、変数の型と値の範囲を正しく理解することで、ほとんどのケースで防止・解決できます。
特に重要なポイントを再確認します。まず、整数型はIntegerではなくLongをデフォルトとして使うという習慣を持つことが根本的な解決策です。次に、整数リテラル同士の演算では計算前に少なくとも一方をCLng関数で変換することが必要です。計算結果にCLngを適用しても効果がない点は多くの開発者がはまる落とし穴ですので特に注意してください。
また、最終行取得やループカウンタにInteger型を使うコードは、Excelのシート行数の拡大によって突然エラーを引き起こします。既存のコードもこの観点で見直すことをお勧めします。
本記事のチェックリストを活用することで、エラー6に遭遇した際に迷わず原因の特定と修正を行えるはずです。