はじめに
VBAで On Error Resume Next を使ってエラーを無視する処理を書く際、特にループの中で使う場合には注意が必要です。VBAの Err オブジェクトは、一度エラー情報を記録すると、次に別のエラーが発生するか、プログラムが終了するまで、そのエラー情報を保持し続けてしまいます。
これにより、ループの1回目の処理で発生したエラーが、エラーが発生しなかった2回目以降の処理でも「エラーが発生した」と誤って判定されてしまう、という問題が起こり得ます。
この問題を解決し、エラー状態を確実にリセットするのが Err.Clear メソッドです。この記事では、Err.Clear の重要性と、ループ処理の中で正しく使う方法について解説します。
Err.Clear を使ったエラー処理のサンプルコード
このマクロは、A1:A5 の各セルに対して割り算 10 / セルの値 を行い、結果をB列に書き込みます。もしA列に 0 や文字列が入っていてエラーが発生した場合は、B列にエラーメッセージを記録します。
完成コード
' ループ内でエラーをチェックし、Err.Clearでリセットする
Sub ClearErrObjectInLoop()
Dim targetCell As Range
' これ以降のエラーを無視して、次の行へ進む
On Error Resume Next
' A1セルからA5セルまでをループ
For Each targetCell In ActiveSheet.Range("A1:A5")
' エラーが発生する可能性のある処理
targetCell.Offset(0, 1).Value = 10 / targetCell.Value
'--- 直後にErr.Numberをチェック ---
If Err.Number <> 0 Then
' エラーが発生した場合
targetCell.Offset(0, 1).Value = "エラー: " & Err.Description
'--- Errオブジェクトをクリアして、次のループに備える ---
' これがないと、次のループでエラーがなくても、このIf文に入ってしまう
Err.Clear
End If
Next targetCell
' エラーハンドリングを通常の状態に戻す
On Error GoTo 0
End Sub
実行前の準備
A1に5、A2に0、A3に2、A4に"abc"、A5に4などを入力してマクロを実行すると、B2とB4にエラーメッセージが、それ以外には計算結果が正しく表示されます。
コードの解説
Err.Clear の重要性
Err.Clear
この一行が、ループ内で On Error Resume Next を安全に使うための鍵です。
Err オブジェクトは、一度 Err.Number が 0 以外になると、その値を保持し続けます。仮に Err.Clear がないと、A2 セル (0) の処理で発生したゼロ除算エラーの情報が Err オブジェクトに残り続けます。そのため、次の A3 セル (2) の処理は正常に成功するにもかかわらず、If Err.Number <> 0 Then のチェック時点では、A2 で発生したエラー情報が残っているため、この If 文が True と判定されてしまいます。
エラー処理のブロック内で Err.Clear を実行することで、Err オブジェクトの状態を「エラーなし(.Number = 0)」にリセットし、次のループの反復処理をクリーンな状態で始められるようにします。
まとめ
今回は、Err.Clear を使ってエラー情報をリセットし、ループ内でのエラー処理を正しく実装する方法を解説しました。
Errオブジェクトは、クリアされるまでエラー情報を保持し続ける。On Error Resume Nextをループ内で使う場合は、エラーを検知して処理した後にErr.Clearを実行し、エラー状態をリセットするのが定石。- これを怠ると、過去のエラーを検知してしまい、予期せぬバグの原因となる。
Err.Clear は、On Error Resume Next を使ったより高度で精密なエラーハンドリングを行う上で、欠かすことのできない重要なメソッドです。
