Visual Basicでは、エラー処理にOn Error(VB6)とTry...Catch(VB.NET)構文が使用されます。
On Error GoTo <Label> — VB6からの古い方法で、エラーが発生した場合に指定されたラベルに移行します。ネストをサポートせず、混乱を招くコードになる可能性があります。Try...Catch...Finally — 現代的な方法(VB.NET)で、例外を扱い、異なるCatchブロックで異なるタイプのエラーを処理することができ、Finallyで最終的なアクションを必ず実行します。例:
VB6:
Sub OpenFile() On Error GoTo ErrorHandler Open "file.txt" For Input As #1 ' ファイルの読み取り Close #1 Exit Sub ErrorHandler: MsgBox "エラー: " & Err.Description End Sub
VB.NET:
Sub OpenFileVBNet() Try Using reader As New StreamReader("file.txt") Dim line As String = reader.ReadLine() End Using Catch ex As IOException MsgBox("エラー: " & ex.Message) Finally ' 常に実行されます End Try End Sub
VB6でOn Error Resume Nextブロック内でエラーが発生した場合、どこで発生したかをどのように知り、正しく処理するにはどうすればよいですか?
正しい答え:
On Error Resume Nextモードでは、プログラムは次の行の実行を続けます。エラーが発生したかどうかを確認するには、呼び出し終了後にErrオブジェクトをチェックする必要があります。
On Error Resume Next ' 一部のコード If Err.Number <> 0 Then MsgBox "エラー: " & Err.Description Err.Clear End If
歴史
VB6からVB.NETに移行する際、一部のハンドラーがOn Error GoToスタイルのまま残され、エラーを暗黙的に飲み込む結果となりました。処理ロジックが混乱し、DBのデータが部分的に空のまま残り、バグは数ヶ月後に発見されました。
歴史
Err.Clearを使用しなかったため、1つのエラーを処理した後、Err.Numberがゼロ以外のままでした。以降のチェックでは、プログラムが新たなエラーが発生したと誤って判断し、誤った処理の分岐に進んでしまいました。
歴史
リファクタリングでOn Error Resume Nextを削除するのを忘れたため、エラーが「飲み込まれ」何のメッセージも表示されませんでした。問題の診断には数時間かかり、アプリケーションは正常に動作しているように見えましたが、実際には重要なデータを失っていました。