2009年4月22日水曜日

Access の VBA でエラー処理

例えば、フォームにレコード を削除するためのボタンがあり、クリックされたときの処理を次のように記述したとする。

Private Sub btnDelete_Click()
    DoCmd.RunCommand acCmdDeleteRecord
End Sub

エラー処理を記述してないので、削除ボタンを押したときに「いいえ」を選択すると、

090422-003

実行時エラーのエラーのダイアログが表示される。

090422-002

 

エラー処理

エラーをキャッチして、エラー番号とエラー内容を表示するように変更するなら、

Private Sub btnDelete_Click()
On Error GoTo Err_Handler
    DoCmd.RunCommand acCmdDeleteRecord
    Exit Sub
    
Err_Handler:
    MsgBox Err.Number & " : " & Err.Description
End Sub

正常に処理されたとき、エラー処理に突入しないように Exit Sub の記述を忘れずに。

先ほどと同じ操作をすると、同じ内容がメッセージボックスに表示される。

090422-004

 

エラー処理の分岐

ところで、ユーザに上記のメッセージを見せる必要はないので、エラーの内容によってエラー処理を変えたい。この場合、先ほどのエラー番号で処理を分ける。

Private Sub btnDelete_Click()
On Error GoTo Err_Hander
    DoCmd.RunCommand acCmdDeleteRecord
    Exit Sub
    
Err_Handler:
    If Err.Number = 2501 Then
        Exit Sub
    Else
        MsgBox Err.Number & "/" & Err.Description
    End If
End Sub

Java ばかりいじっていたとき、エラー番号でトラップするのを見たときびびったけど ^^;

ちなみに Chapter 09 例外処理 - @IT によると、

VB.NETでは、On Error Gotoは「非構造化例外処理」という名前で呼ばれる

 

後処理がある場合

もし、次のような要件がある場合は、

  • エラーの内容に応じて処理をしたい
  • 正常、エラーを問わず後処理が必要
Private Sub btnDelete_Click()
On Error GoTo Err_Handler
    DoCmd.RunCommand acCmdDeleteRecord

Finally:
    ' 後処理
    Exit Sub

Err_Handler:
    If Err.Number = 2501 Then
        ' このエラー独自の処理
    Else
        MsgBox Err.Number & "/" & Err.Description
    End If
    Resume Finally
End Sub

(cf. Access の VBA でトランザクション処理 – CSV ファイルからデータの登録)

処理がシンプルなときは Resume Next でもいいけれど、バグを誘発しそうなので Resume ラベル名 を使うことにしようかな。