はじめに
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
を使ったより高度で精密なエラーハンドリングを行う上で、欠かすことのできない重要なメソッドです。