VBAではエラーが発生しても、処理を継続させるための構文として On Error Resume Next が用意されている。
これを使えば、エラー発生時にも処理位置が次の行に移って、処理が継続される。
Visual Basic言語リファレンス On Error ステートメント
On Error Resume Next は、実行時エラーを発生させたステートメントの直後のステートメント、または、On Error Resume Next ステートメントを含むプロシージャの最新の呼び出しに続くステートメントで、実行を続行します。
うん、まあだいたいは分かるけど、If文の判定条件でエラーが発生したりすると、制御はどこに移動するんだろう?
判定条件がTrueと解釈されるのだろうか?
うーん、ループも試してみよう。
判定条件がTrueと解釈される訳ではないようだ。
確かにそれを頭に入れて、リファレンスの説明を読み直すと、そういう風にも読める。
そもそもGotoが構文の意味に関わらず、指定されたラベル(行)に移動することを考えれば、上記の動作仕様も自然なものに思える。
つまり、"On Error Goto 次の行" ということだね。
でも、これが意図したエラートラップにつながるとは思えないし、On Error Resume Next を使った時は条件判定内にエラーが発生しうる処理は入れない方がよさそう。
これを使えば、エラー発生時にも処理位置が次の行に移って、処理が継続される。
Visual Basic言語リファレンス On Error ステートメント
On Error Resume Next は、実行時エラーを発生させたステートメントの直後のステートメント、または、On Error Resume Next ステートメントを含むプロシージャの最新の呼び出しに続くステートメントで、実行を続行します。
うん、まあだいたいは分かるけど、If文の判定条件でエラーが発生したりすると、制御はどこに移動するんだろう?
わざとエラーを発生させる
試しにこんな関数を用意してみよう。Private Function RaiseError(ByVal n As Long) As Boolean RaiseError = True If n = 0 Then Err.raise 5 ElseIf n < 0 Then RaiseError = False End If End Functionnが正の場合はTrueを返して、nが負の場合はFalseを返す。nが0の場合はエラーを発生させる。
Ifの場合
こんな感じで呼べば、判定条件が True And False になるので、If文の中には到達しない。On Error Resume Next If RaiseError(1) And RaiseError(-1) Then Debug.Print "到達不能..." End Ifじゃあ、これはどうだろう。
On Error Resume Next If RaiseError(1) And RaiseError(-1) And RaiseError(0) Then Debug.Print "なぜか到達..." Else Debug.Print "到達しない." End Ifこれを実行すると、"なぜか到達..."が出力される。
判定条件がTrueと解釈されるのだろうか?
うーん、ループも試してみよう。
ループの場合
On Error Resume Next Do While RaiseError(0) Debug.Print "無限ループ..." Loopこれは無限ループになる。
On Error Resume Next Do Until RaiseError(0) Debug.Print "無限ループ..." Loopこれも無限ループになる。
判定条件がTrueと解釈される訳ではないようだ。
On Error Resume Next Do Debug.Print "一度だけ実行..." Loop While RaiseError(0)これは一度だけ実行される。
結局...
どうも判定条件がTrueになるとか、Falseになるとかいうことではなく、ソースコードの字面上まさに次のステートメントに制御が移るということみたい。確かにそれを頭に入れて、リファレンスの説明を読み直すと、そういう風にも読める。
そもそもGotoが構文の意味に関わらず、指定されたラベル(行)に移動することを考えれば、上記の動作仕様も自然なものに思える。
つまり、"On Error Goto 次の行" ということだね。
でも、これが意図したエラートラップにつながるとは思えないし、On Error Resume Next を使った時は条件判定内にエラーが発生しうる処理は入れない方がよさそう。
0 件のコメント:
コメントを投稿