Excelマクロの実行中に突然表示される「実行時エラー’11’: 0 で除算しました。」というエラー。コードを見ても一見どこが問題なのかわからない、テスト中は正常に動いていたのに本番データで初めてエラーが出た——そういった経験をした方も多いのではないでしょうか。
このエラーは、割り算の分母(除数)がゼロになったときに発生します。数学的にゼロで割る計算は定義できないため、VBAも処理を強制停止します。原因は単純に見えますが、「なぜ分母がゼロになったのか」を突き止め、適切なゼロチェックを実装するには、いくつかの知識が必要です。
本記事では、Microsoft公式ドキュメント(Office VBA リファレンス)をはじめとする信頼性の高い情報源をもとに、エラー11の発生原因・見落としやすいパターン・各種ゼロチェックの書き方・On Errorを使ったエラーハンドリングまでを体系的に解説します。
目次
- 実行時エラー’11’(ゼロ除算)とは何か
- 原因1:変数の値が直接ゼロになっている
- 原因2:スペルミスで変数が暗黙的にゼロ初期化された
- 原因3:セルが空白・未入力の状態で除算した
- 原因4:引数として渡された変数がゼロだった
- 原因5:Mod演算子の除数がゼロになった
- 原因6:分子もゼロのときはエラー6(オーバーフロー)になる
- ゼロチェックの基本:If文による条件分岐
- IIf関数を使った1行ゼロチェック
- IsNumeric関数・IsEmpty関数を組み合わせたチェック
- On Errorを使ったエラーハンドリング
- ループ処理の中でのゼロチェック実装
- エラー箇所の特定方法(デバッグ手順)
- 解決方法チェックリスト
- よくある質問(FAQ)
1. 実行時エラー’11’(ゼロ除算)とは何か
実行時エラー’11’「0 で除算しました。」は、割り算の除数(分母)がゼロになったときに発生するエラーです。Microsoftの公式VBAリファレンスでは「ゼロによる除算は使用できません」と定義されており、以下の2つが主な原因として挙げられています。
- 除数として使用されている式の値がゼロである
- 変数名のスペルが誤っていて、ゼロに初期化される数値変数が暗黙的に作成されている
また、数値の0だけでなく空白(ブランク)のセルで除算してもエラー11が発生します。空白セルの値をVBAが数値として扱う際、0として処理されるためです。
VBAでの割り算には通常の除算(/)、整数除算(\)、剰余演算(Mod)の3種類があります。いずれも除数がゼロの場合にエラー11が発生します。
| 演算子 | 役割 | 例 | 除数ゼロの挙動 |
|---|---|---|---|
| / | 浮動小数点除算 | 10 / 2 → 5.0 | エラー11発生 |
| \ | 整数除算(商のみ) | 10 \ 3 → 3 | エラー11発生 |
| Mod | 剰余(余り) | 10 Mod 3 → 1 | エラー11発生 |
2. 原因1:変数の値が直接ゼロになっている
最もシンプルなケースです。変数に明示的にゼロを代入した状態、または初期化直後(VBAでは数値型変数は宣言と同時に0で初期化される)のままの変数を除数として使ってしまった場合に発生します。
' NG例:変数yが0のため エラー11発生
Sub Sample_NG1()
Dim x As Long
Dim y As Long
x = 10
y = 0 ' 明示的にゼロを代入
Debug.Print x / y ' エラー11発生
End Sub
' OK例:If文でゼロチェックしてから除算する
Sub Sample_OK1()
Dim x As Long
Dim y As Long
x = 10
y = 0
If y = 0 Then
Debug.Print 0 ' 分母がゼロの場合の代替処理
Else
Debug.Print x / y ' ゼロでなければ通常の除算
End If
End Sub
3. 原因2:スペルミスで変数が暗黙的にゼロ初期化された
Microsoftの公式ドキュメントが特に注意を促しているケースです。変数名のスペルを誤ると、ゼロに初期化された別の数値変数が暗黙的に作成される可能性があります。これはVBAで Option Explicit を宣言していない場合に発生します。
' NG例:Option Explicitなしのコード(スペルミスで別変数が生成される)
' ※このモジュールにはOption Explicitがない前提
Sub Sample_NG2()
Dim totalCount As Long
totalCount = 100
' 「totalCount」を「totalCont」と誤って記述してしまった
' VBAは「totalCont」という新しいVariant変数をゼロで初期化して使う
Debug.Print 50 / totalCont ' totalContは0 → エラー11発生
End Sub
' OK例:Option Explicitでスペルミスをコンパイル時に検出する
Option Explicit ' ← モジュール先頭に必ず記述
Sub Sample_OK2()
Dim totalCount As Long
totalCount = 100
' 「totalCont」と書くとコンパイルエラーになり、実行前に気づける
Debug.Print 50 / totalCount ' 正しい変数名ならエラーなし
End Sub
Option Explicit は変数宣言を強制するキーワードです。VBEの「ツール」→「オプション」→「変数の宣言を強制する」にチェックを入れると、新規作成したモジュールに自動的に追加されるようになります。
4. 原因3:セルが空白・未入力の状態で除算した
実務でもっとも頻繁に発生するパターンです。数値の0だけでなく、空白(ブランク)のセルで除算してもエラー11が発生します。VBAは空白セルの値を数値として扱う際に0と解釈するためです。
ユーザーが入力し忘れたセル、フィルタで非表示になったデータの空行、条件によって値が入らなかったセルなどが典型的な発生源です。
' NG例:セルB1が空白の場合にエラー11発生
Sub Sample_NG3()
Dim result As Double
result = Range("A1").Value / Range("B1").Value ' B1が空白 → 0除算でエラー11
End Sub
' OK例:空白チェックと数値チェックを組み合わせる
Sub Sample_OK3()
Dim result As Double
Dim denominator As Variant
denominator = Range("B1").Value
' 空白チェックと数値チェックを組み合わせる
If denominator = "" Or denominator = 0 Or Not IsNumeric(denominator) Then
MsgBox "B1に有効な数値を入力してください。"
result = 0
Else
result = Range("A1").Value / CDbl(denominator)
Debug.Print result
End If
End Sub
5. 原因4:引数として渡された変数がゼロだった
公式ドキュメントでも明示されている通り、他のプロシージャから引数として渡された変数の値がゼロだった場合もエラー11が発生します。呼び出し元ではゼロ以外の値が設定されているつもりでも、計算の過程でゼロになるケースがこれに該当します。
' NG例:呼び出し元でゼロになった引数が渡される
Sub CallerSub()
Dim baseVal As Long
baseVal = 0 ' 何らかの計算でゼロになってしまった場合
Call CalcRate(100, baseVal) ' baseValが0のまま渡されるとエラー
End Sub
Sub CalcRate(numerator As Double, denominator As Double)
Dim rate As Double
rate = numerator / denominator ' denominatorが0 → エラー11発生
MsgBox "達成率: " & Format(rate, "0.0%")
End Sub
' OK例:受け取った側でもゼロチェックを行う
Sub CalcRate_Safe(numerator As Double, denominator As Double)
If denominator = 0 Then
MsgBox "分母がゼロのため計算できません。"
Exit Sub
End If
Dim rate As Double
rate = numerator / denominator
MsgBox "達成率: " & Format(rate, "0.0%")
End Sub
このように、引数を受け取るプロシージャ側でもゼロチェックを行うことが、防御的なコーディングの基本です。呼び出し元のデータが正しいことを保証できない場合(ユーザー入力やセルから取得したデータを引数にする場合)は特に重要です。
6. 原因5:Mod演算子の除数がゼロになった
Mod演算子(剰余演算)でも除数がゼロになるとエラー11が発生します。奇数・偶数判定や周期処理などでModを使う際に見落としがちです。
' NG例:Mod演算の除数がゼロになるとエラー11
Sub Sample_NG5()
Dim n As Long
Dim d As Long
n = 15
d = 0
Debug.Print n Mod d ' エラー11発生
End Sub
' OK例:Modでもゼロチェックが必要
Sub Sample_OK5()
Dim n As Long
Dim d As Long
n = 15
d = 0
If d = 0 Then
MsgBox "除数がゼロのため剰余を計算できません。"
Else
Debug.Print n Mod d
End If
End Sub
なお、Mod演算子では除数や被除数に小数を使っても構文エラーにはなりません。ただし、VBAは内部的に「銀行丸め(偶数丸め)」で整数に変換してから計算します。例えば「11 Mod 2.5」は2.5が銀行丸めで2に変換されるため「11 Mod 2 = 1」となります。この挙動は通常の四捨五入とは異なるため、小数を使ったMod演算では結果に注意が必要です。
7. 原因6:分子もゼロのときはエラー6(オーバーフロー)になる
これは多くの解説サイトでも触れられている重要な落とし穴です。分母のみが0の場合はエラー11(0で除算しました)、分子も分母も0の場合はエラー6(オーバーフロー)が発生します。
' エラーの種類の違いを確認するコード
Sub ZeroDivisionComparison()
Dim numerator As Long
Dim denominator As Long
' パターン1:分母のみ0 → エラー11(0で除算しました)
numerator = 10
denominator = 0
' Debug.Print numerator / denominator ' エラー11
' パターン2:分子も分母も0 → エラー6(オーバーフロー)
numerator = 0
denominator = 0
' Debug.Print numerator / denominator ' エラー6
' ゼロチェックで両方のパターンを回避
If denominator = 0 Then
Debug.Print "除算不可(分母がゼロ)"
Else
Debug.Print numerator / denominator
End If
End Sub
分母がゼロかどうかをチェックさえすれば、どちらのケースも回避できます。分子がゼロかどうかを別途チェックする必要はありません。
8. ゼロチェックの基本:If文による条件分岐
エラー11を防ぐ最も基本的な方法は、除算を行う前にIf文で除数がゼロでないかを確認することです。ゼロだった場合の代替処理(0を返す、メッセージを表示する、処理をスキップするなど)も合わせて実装します。
8-1. シンプルなIf〜Elseによるゼロチェック
' パターン1:ゼロなら0を返す
Sub ZeroCheck_Basic1()
Dim x As Double
Dim y As Double
Dim result As Double
x = 100
y = 0
If y = 0 Then
result = 0 ' 分母がゼロの場合は0とみなす
Else
result = x / y
End If
Debug.Print "結果: " & result
End Sub
' パターン2:ゼロなら処理を中断してメッセージを表示
Sub ZeroCheck_Basic2()
Dim x As Double
Dim y As Double
x = Range("A1").Value
y = Range("B1").Value
If y = 0 Then
MsgBox "B1の値がゼロです。正しい値を入力してください。", vbExclamation, "入力エラー"
Exit Sub ' プロシージャを終了
End If
Dim result As Double
result = x / y
Range("C1").Value = result
End Sub
8-2. セルのデータを一括処理する場合のゼロチェック
' 達成率を一括計算する例(C列 = A列 / B列)
Sub CalcAchievementRate()
Dim i As Long
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To rowEnd
Dim actual As Variant
Dim target As Variant
actual = Cells(i, 1).Value ' A列:実績値
target = Cells(i, 2).Value ' B列:目標値(除数)
' 数値チェックとゼロチェックを組み合わせる
If IsNumeric(target) And CDbl(target) <> 0 Then
Cells(i, 3).Value = Format(CDbl(actual) / CDbl(target), "0.0%")
Else
Cells(i, 3).Value = "N/A" ' 目標がゼロまたは非数値の場合
End If
Next i
MsgBox "達成率の計算が完了しました。"
End Sub
9. IIf関数を使った1行ゼロチェック
IIf関数を使うと、If〜Else〜End Ifを1行で書くことができます。コードを短く記述したい場面で有効です。ただし、IIf関数はTrueとFalseの両方の式を必ず評価するという性質があります。そのため除数がゼロの場合でもFalseの評価式(除算)が実行され、エラーが発生します。これを避けるため、ゼロの場合は固定値を返すようにします。
' IIf関数を使ったゼロチェックの書き方
Sub ZeroCheck_IIf()
Dim x As Double : x = 100
Dim y As Double : y = 0
' IIf(条件, Trueのときの値, Falseのときの値)
' ※注意:IIf は両辺を評価するため、y=0 でも除算が実行されエラーになる場合がある
' そのため「ゼロなら0を返す」パターンで使う(除算はFalse側のみ)
Dim result As Double
result = IIf(y = 0, 0, x / y)
' ↑ゼロの場合は0を返す(x/yは評価されない保証はない)
' ★より安全なのはIf文を使うこと。IIfは簡易な用途に留める
Debug.Print "結果: " & result
End Sub
IIf関数は簡潔に書けるメリットがありますが、両辺評価の問題があるため複雑な除算には使わないことを推奨します。コードの読みやすさと安全性を優先する場合はIf〜End Ifを使いましょう。
10. IsNumeric関数・IsEmpty関数を組み合わせたチェック
セルの値を除数として使う場合、ゼロかどうかだけでなく、「数値として有効な値かどうか」も同時にチェックすることが重要です。空白・文字列・エラー値が入力されているセルをそのまま除数として使おうとしても、エラーが発生します。
10-1. IsNumericで数値チェックする
IsNumeric関数は、引数が数値として解釈できる場合にTrueを返します。空白文字列(“”)や通常の文字列に対してはFalseを返すため、ゼロチェックと組み合わせて使うと安全です。
' IsNumericとゼロチェックを組み合わせた安全な除算
Sub SafeDivision_IsNumeric()
Dim val As Variant
val = Range("B1").Value ' セルの値をVariantで受け取る
If Not IsNumeric(val) Then
MsgBox "B1に数値が入力されていません。"
Exit Sub
End If
If CDbl(val) = 0 Then
MsgBox "B1の値がゼロです。"
Exit Sub
End If
Dim result As Double
result = CDbl(Range("A1").Value) / CDbl(val)
MsgBox "計算結果: " & result
End Sub
10-2. IsEmptyで未入力チェックをする
IsEmpty関数は変数やセルが初期化されていない(値が設定されていない)状態のときにTrueを返します。セルが一度も入力されていない場合に有効なチェックです。
' IsEmptyで未入力を確認してからゼロチェックを行う
Sub SafeDivision_IsEmpty()
Dim cell As Range
Set cell = Range("B1")
If IsEmpty(cell) Then
MsgBox "B1が未入力です。"
Exit Sub
End If
If Not IsNumeric(cell.Value) Then
MsgBox "B1に数値以外が入力されています。"
Exit Sub
End If
If CDbl(cell.Value) = 0 Then
MsgBox "B1の値がゼロです。"
Exit Sub
End If
Dim result As Double
result = CDbl(Range("A1").Value) / CDbl(cell.Value)
MsgBox "計算結果: " & result
End Sub
10-3. まとめてチェックする汎用関数の作成
ゼロチェックを何度も書くのが面倒な場合は、除算処理を汎用関数としてまとめておく方法が便利です。
' 安全な除算を行う汎用Function(ゼロの場合はdefaultValueを返す)
Function SafeDivide(numerator As Double, denominator As Double, _
Optional defaultValue As Double = 0) As Double
If denominator = 0 Then
SafeDivide = defaultValue ' ゼロの場合はデフォルト値を返す(既定は0)
Else
SafeDivide = numerator / denominator
End If
End Function
' 使用例
Sub UseSafeDivide()
Dim r1 As Double
Dim r2 As Double
r1 = SafeDivide(100, 4) ' → 25.0
r2 = SafeDivide(100, 0) ' → 0(デフォルト値)
r2 = SafeDivide(100, 0, -1) ' → -1(カスタムデフォルト値)
Debug.Print "r1 = " & r1
Debug.Print "r2 = " & r2
End Sub
11. On Errorを使ったエラーハンドリング
どうしてもゼロになる条件を事前に洗い出しきれない場合や、複数のエラーを一括して処理したい場合には、On Errorステートメントを使ったエラーハンドリングが有効です。ただし、On Error Resume Nextを安易に使うとエラーを握りつぶしてデータが壊れる原因になるため、慎重に使う必要があります。
11-1. On Error GoToを使ったエラートラップ
' On Error GoToで エラー11を含む複数エラーを処理する
Sub Sample_OnErrorGoTo()
Dim num1 As Double
Dim num2 As Double
Dim result As Double
num1 = 100
num2 = 0
On Error GoTo ErrHandler ' エラーが発生したらErrHandlerへジャンプ
result = num1 / num2 ' ここでエラー11発生
MsgBox "結果: " & result
Exit Sub ' 正常終了(ErrHandlerを飛ばす)
ErrHandler:
Select Case Err.Number
Case 11
MsgBox "ゼロ除算エラーが発生しました。" & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"内容: " & Err.Description, vbCritical, "エラー"
Case Else
MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"内容: " & Err.Description, vbCritical, "エラー"
End Select
End Sub
11-2. On Error Resume Nextを使うパターン(注意点あり)
On Error Resume Nextを使うと、エラーが発生した行をスキップして次の行から処理を続けます。ループ処理の途中でゼロ除算が起きても処理を継続させたい場合に使えますが、エラー後の変数の値が不正なままになるリスクがあるため、必ずErr.Numberで発生したエラーを確認してください。
' On Error Resume Nextで処理を継続する(ループ内の部分的な失敗を許容する場合)
Sub Sample_ResumeNext()
Dim i As Long
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To rowEnd
Dim actual As Double
Dim target As Double
actual = CDbl(Cells(i, 1).Value)
target = CDbl(Cells(i, 2).Value)
Dim rate As Double
On Error Resume Next ' エラーが発生しても次の行へ進む
rate = actual / target
If Err.Number = 11 Then ' ゼロ除算エラーが発生したか確認
rate = 0 ' エラー時は0を代入
Err.Clear ' エラー状態をリセット(重要)
End If
On Error GoTo 0 ' エラートラップを解除する(必ず実施)
Cells(i, 3).Value = Format(rate, "0.0%")
Next i
End Sub
On Error Resume Nextを使う場合は、必ず On Error GoTo 0 でエラートラップを解除し、Err.Clear でエラー状態をリセットすることが重要です。これを怠ると、後続の無関係なエラーもすべて無視されてしまいます。
12. ループ処理の中でのゼロチェック実装
実務ではループの中で大量のデータを処理することが多く、特定の行だけ除数がゼロになるケースへの対応が重要です。以下は実務でそのまま使えるパターンを示します。
12-1. 部門別達成率を集計するパターン
' 部門別の目標達成率を計算(目標値ゼロまたは空白の行はスキップ)
Sub CalcDeptAchievement()
Dim i As Long
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
Dim skipCount As Long
skipCount = 0
For i = 2 To rowEnd
Dim deptName As String
Dim actual As Variant
Dim target As Variant
deptName = Cells(i, 1).Value ' A列:部門名
actual = Cells(i, 2).Value ' B列:実績
target = Cells(i, 3).Value ' C列:目標(除数)
' ゼロ・空白・非数値チェック
If target = "" Or Not IsNumeric(target) Or CDbl(target) = 0 Then
Cells(i, 4).Value = "目標未設定"
skipCount = skipCount + 1
Else
Cells(i, 4).Value = Format(CDbl(actual) / CDbl(target), "0.0%")
End If
Next i
MsgBox "計算完了。スキップ行数: " & skipCount & "行", vbInformation
End Sub
12-2. 合計値で割って構成比を求めるパターン
' 全体の合計に対する各行の構成比を計算
Sub CalcShareRate()
Dim i As Long
Dim rowEnd As Long
rowEnd = Cells(Rows.Count, 1).End(xlUp).Row
' まず全体合計を計算
Dim total As Double
total = WorksheetFunction.Sum(Range(Cells(2, 1), Cells(rowEnd, 1)))
' 合計がゼロの場合は処理を中断
If total = 0 Then
MsgBox "合計値がゼロのため、構成比を計算できません。", vbExclamation
Exit Sub
End If
' 各行の構成比を計算
For i = 2 To rowEnd
Cells(i, 2).Value = Format(CDbl(Cells(i, 1).Value) / total, "0.0%")
Next i
MsgBox "構成比の計算が完了しました。"
End Sub
13. エラー箇所の特定方法(デバッグ手順)
エラー11が発生した際は、以下の手順でエラーの発生箇所と原因を特定してください。
13-1. デバッグボタンでエラー行を確認する
エラーダイアログが表示されたら「デバッグ」ボタンをクリックしてください。VBE(Visual Basic Editor)上で、エラーが発生した行が黄色くハイライトされます。その行の除算式を確認し、どの変数が除数になっているかを特定します。
13-2. イミディエイトウィンドウで変数の値を確認する
デバッグモードで処理が停止中に、VBEの「表示」→「イミディエイト ウィンドウ」(Ctrl+G)を開き、除数として使っている変数の値を確認します。
' デバッグ停止中にイミディエイトウィンドウで確認するコマンド例
? denominator ' 除数の変数の値を表示
? TypeName(denominator) ' 除数の型を確認
? Range("B1").Value ' 特定セルの値を確認
? IsNumeric(Range("B1").Value) ' そのセルが数値かどうか確認
13-3. ブレークポイントとステップ実行で追跡する
除算が行われる周辺の行にブレークポイントを設定し、F8キーで1行ずつ実行することで、どのタイミングで変数がゼロになったかを追跡できます。特に、複数のプロシージャをまたぐ処理では、どの段階でゼロになったかを確認することが重要です。
' デバッグ用:変数の状態を出力するコードを一時的に追加する
Sub DebugPrint_Sample()
Dim x As Double : x = 100
Dim y As Double : y = GetDenominator() ' 別関数から取得
' デバッグ時に値を確認するためDebug.Printを追加
Debug.Print "x = " & x & ", y = " & y & ", IsNumeric(y) = " & IsNumeric(y)
If y <> 0 Then
Debug.Print "result = " & x / y
End If
End Sub
14. 解決方法チェックリスト
エラー11が発生したときに、上から順番に確認してください。
- エラーダイアログの「デバッグ」ボタンを押し、エラー発生行の除算式と除数変数を特定する
- 除数の変数または式の値が、実行時にゼロになっていないかイミディエイトウィンドウで確認する
- 除算の前に
If denominator = 0 Thenのゼロチェックを追加する - セルの値を除数として使う場合は、空白チェック(
= "")と IsNumeric チェックも追加する - Option Explicit を宣言していない場合は追加し、スペルミスによる暗黙的なゼロ変数を排除する
- 他のプロシージャから引数として渡された除数についても、受け取る側でゼロチェックを行う
- Mod演算子を使っている場合もゼロチェックを追加する
- ループ内でゼロ除算が起きる場合は、該当行をスキップまたは代替値を設定する処理を追加する
- 複数のエラーをまとめて処理する場合は、On Error GoToでErrHandlerを実装する
- On Error Resume Nextを使う場合は、必ずErr.Numberの確認とErr.ClearおよびOn Error GoTo 0を実施する
- 汎用の SafeDivide 関数を作成してゼロチェックを一元化することを検討する
15. よくある質問(FAQ)
Q1. テスト中は問題なかったのに、本番データで初めてエラー11が出ました。なぜですか?
テストデータには除数がゼロになるケースが含まれていなかったためです。実務データではユーザーが入力し忘れたセル・目標値が設定されていない行・計算の結果としてゼロになったケースなど、テストでは想定していなかった条件が発生することがあります。数値データを除数として使う箇所にはすべてゼロチェックを実装することを推奨します。
Q2. 0除算を避けるためにWorksheetFunctionのIFERROR相当の処理はVBAでできますか?
VBAには、ExcelのIFERROR関数に直接対応する機能はありません。代わりに、本記事で紹介した If文によるゼロチェック、SafeDivide汎用関数、On Error Resume Nextを使って同等の処理を実装します。ただし、WorksheetFunction.IfError を組み合わせてセルの数式をVBAから制御することは可能です。
Q3. 分母がゼロになったときに0を返すか、エラーメッセージを出すか、どちらが良いですか?
用途によって異なります。達成率・構成比などの計算では「目標・合計が未設定」という意味として “N/A” や空欄を設定するほうが適切な場合が多いです。バッチ処理や集計マクロでは処理をスキップしてカウントする方法が実用的です。ユーザーが入力するフォームでは、その場でメッセージを表示して再入力を促す方法が向いています。
Q4. On Error Resume Nextは使わないほうが良いですか?
安易に使うべきではありませんが、ループ内でエラーを含む行をスキップしながら処理を継続させるケースでは有効な手段です。重要なのは、Err.Number で発生したエラーの種類を必ず確認すること、Err.Clear でエラー状態をリセットすること、処理後に On Error GoTo 0 でトラップを解除することです。これらを守れば、On Error Resume Nextは安全に使えます。
Q5. IsNumericとIsEmptyのどちらを使えばよいですか?
目的が異なります。IsEmpty は変数やセルが「まったく値を持っていない(初期化されていない)」状態を判定します。IsNumeric は「数値として解釈できるか」を判定します。セルのチェックには IsNumeric が広く使えますが、セルが一度も入力されたことがない場合を特別扱いしたいときは IsEmpty を組み合わせてください。また、IsNumeric は “1.5” のような数値形式の文字列もTrueを返す点に注意が必要です。
まとめ
Excelマクロの実行時エラー’11’(ゼロ除算)は、発生の仕組み自体はシンプルですが、「なぜ除数がゼロになったのか」の原因は多岐にわたります。
Microsoft公式ドキュメントが示す通り、主な原因は「除数の値が直接ゼロ」「変数名のスペルミスによる暗黙的なゼロ初期化」「引数として渡された値のゼロ」の3つです。これに加えて実務では「空白セルの除算」「Mod演算子のゼロ」「ループ中の特定行でのゼロ」といったケースが頻繁に発生します。
解決の基本は除算の前にIf文でゼロチェックを行うことです。セルの値を使う場合はIsNumericや空白チェックも組み合わせ、汎用のSafeDivide関数にまとめることでコードの保守性も高まります。
また、Option Explicit の宣言は変数のスペルミスによる意図しないゼロ初期化を防ぐ有効な手段です。すべてのモジュールに必ず記述する習慣をつけてください。
本記事のチェックリストを活用することで、エラー11に遭遇した際も迷わず原因を特定し、適切なゼロチェックを実装できるはずです。