Top / プログラミングテクニック / 18.エラー処理を考える

一般的なエラートラップ

よく見かけるのは、

error1.gif

というメッセージボックスを出して、ユーザに処理を選択させるものだと思います。

「中止」ボタン処理を異常終了します。
「再試行」ボタンもう一度、処理を繰り返します。
「無視」ボタンエラーを無視して処理を続行します。

これを、VB でコーディングすると、以下の様になります。

Private Sub ErrTrap()

    On Error GoTo Err_Handler:

    (処理)

   Exit Sub

Err_Handler:
    Select Case MsgBox(Err.Description, vbAbortRetryIgnore, Err.Source)
        Case vbRetry
            Resume
        Case vbIgnore
            Resume Next
        Case vbAbort
            MsgBox "中断しました。"
    End Select
End Sub

サブルーチンや、関数を呼び出している場合

たとえば、SubA から、SubB を呼び出している場合を考えます。

Private Sub SubA()

    On Error GoTo Err_Handler:
        ・
        ・
    Call SubB
        ・
        ・
    Exit Sub

Err_Handler:
    Select Case MsgBox(Err.Description, vbAbortRetryIgnore, Err.Source)
        Case vbRetry
            Resume
        Case vbIgnore
            Resume Next
        Case vbAbort
            MsgBox "中断しました。"
    End Select
End Sub

Private Sub SubB()
    Dim C As Long
    ・
    ・
     C = 1 / 0               ' エラーが起きます。
    ・
    ・
End Sub

このような場合、SubB でエラーが発生するわけですが、 SubB の中では、エラートラップを行っていないので、エラーが発生したときの飛び先は、 SubA の Err_Handler になります。

さて、このとき、Resume , Resume Next の飛び先は、どうなるかというと、

ResumeCall SubB から実行する
Resume NextCall SubB の次を実行する

となります。

ところで、ちょっと気をつけないといけないことがあります。

後処理が必要なサブルーチン

さて、SubB の中で、ファイルを開いていた場合、どうなるでしょう。

Private Sub SubB()
    Dim intFno As Integer
    Dim C As Long
    intFno = FreeFile
    Open "hoge.dat" For Input As #intFno
    ・
    ・
    C = 1 / 0               ' エラーが起きます。
    ・
    ・
    Close #intFno
End Sub

このままでは、ファイルを開いたまま、エラールーチンに飛ぶことになります。
つまり、使われないファイルハンドルが、いつまでも存在することになるわけです。

このような処理をほうっておくと、これ以降の処理で、予期しない動きに悩ませられることになります。
つぎのようにコーディングすれば、回避することができます。

Private Sub SubB()
   Dim intFno As Integer
   Dim C As Long

   intFno = FreeFile
   Open "hoge.dat" For Input As #intFno

   On Error GoTo Err_Handler
   ・
   ・
   C = 1 / 0               ' エラーが起きます。
   ・
   ・
   Close #intFno
   Exit Sub
Err_Handler:
   Close #intFno
   Err.Raise Err.Number, Err.Source, Err.Description
End Sub

最初にファイルをオープンできたら、エラートラップを行い、エラー処理では、ファイルをクローズします。
さらに、SubA のエラールーチンに飛ぶため、エラーを起こしています。

エラー処理でエラートラップ

エラー処理をやっているときにエラートラップを行いたい場合、Resume で戻ってやる必要があります。

Private Sub SubB()

    On Error GoTo Err_Handler

    (処理)

    Exit Sub
Err_Handler:

    Resume After_Err

After_Err:
    On Error Goto After_Err_Handler:

    Exit Sub
After_Err_Handler:

End Sub

でも、これだと処理が見づらくなるので、エラー処理はひとつのサブルーチンやファンクションにしたほうがいいと思います。

具体的には

Private Sub SubB()

    On Error GoTo Err_Handler

    (処理)

    Exit Sub
Err_Handler:
    Call Err_SubB
End Sub

Private Sub Err_SubB()
    On Error Goto Err_Handler:

    Exit Sub
Err_Handler:
    Err.Raise Err.Number, Err.Source, Err.Description
End Sub



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2009-10-25 (日) 23:55:54 (2852d)