投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/8/19 18:30:11
うわーっ。 ごめんなさい、On Error 版の修正案、今見たらバグってました。
ということで、先の回答は Try~Catch 案の方を参考にしてください…。

------

On Error 版については、本来の流れとしては、
 ・Err.Number = 0 はもちろん正常処理。
 ・Err.Number = 5 が今回行う例外処理。
 ・それ以外のエラーは例外のままとする。
を書こうとしていたのですが、先のコードだと、Err.Number ≠ 5 なエラーが発生した場合に、
エラーが握りつぶされてしまいますので、正しい処理にはなっていませんでした。すみません。
(たとえば、FileNotFoundException が発生した場合は、Err.Number が 53 を返します)

とりあえず、If Err.Number <> 0 Then に変更すれば、エラーを握り潰してしまうことは無くなりますが、
今度は想定外のエラーまでも処理対象になってきてしまうので、これも避けておきたいところ。


今回の処理では、想定外の例外はトラップしていなかったことにしておきたいので、
呼び出し元にそのまま例外を渡せるよう、できれば例外を投げ直したいところですが、
残念ながら、引数なしでの「Throw」呼び出しは、Catch ブロックでないと使えないので、
ElseIf Err.Number <> 0 Then
    Dim ex As Exception = Err.GetException()
    On Error GoTo 0
    Throw New InvalidOperationException("想定外のエラーです。", ex)
End If
として代用するぐらいしか思いつきませんでした。
この点では Catch を使う方がスマートですね。

なお、上記のコードを
ElseIf Err.Number <> 0 Then
    Dim ex As Exception = Err.GetException()
    On Error GoTo 0
    Throw ex
End If
にしてしまうと、エラー発生個所に関する情報(StackTrace)が失われてしまう事になります。

元の例外(ex)から得られる StackTrace には、Check 内でエラーが発生したことが示されていますが、
それを再度 Throw ex してしまうと、投げ直した箇所(Button1_Click 内)でエラーが生成されたという
情報へと StackTrace が変化してしまい、情報の一部を欠落させてしまいます。
(引数なしの Throw 呼び出しでは、StackTrace は変化しません)

まぁ、「Throw New InvalidOperationException("想定外のエラーです。", ex)」としても
StackTrace が Button1_Click 内を指してしまうという点では変わらないのですが…この場合は
InnerException 経由で本来の StackTrace を得られるため、情報は *一応* 残せます。