vbaでは例外機構はない。
したがって、組込みの実行時エラーか、独自のエラーをハンドリングすることになる。
###Errオブジェクト
C言語のようにエラーに対応する整数値を扱うことができる。
主なメソッドとしてNumberメソッドだろう。
Error関数を利用してErr.Numberに対応するエラーメッセージを投げられる。
Error(Err.Number)
自分でセットするなら次のようにする。
事前条件
If cond Then
Err.Raize Number:= 999, Description:="something went wrong"
End if
事後条件
On Error Goto Have_Err
Have_Err:
If Err.Number = 999 Then
msgbox Err.Description
End if
実際には次のように書く
Private Sub f1(ByVal v as Integer)
If v < 0 Then
Err.Clear
Err.Raise Number:=999, Description:="something went wrong"
End if
End Sub
Private Sub f2()
On Error Goto Have_Err
Call f1(-1)
Have_Err:
If Err.Number = 999 Then
MsgBox Err.Number & vbCrLf & Err.Description
Exit Sub
End If
End Sub
見ての通り例外のようなことができる。
プロシージャf1 ではErrオブジェクトにエラー値の設定のみしておき、プロシージャ呼び出しでエラーをチェックする。
これはErrオブジェクトがパブリック・スコープを持つため可能になる。
ただパブリック・スコープを持つのためErr.Clearでエラー値をリセットしておく必要がある。
余談ながら、システムによっては「例外」をうまく利用してメモリ割り当てなどを行っている。
C言語ではこれを抽象化してシグナルというものをユーザーに公開している。
C++では更に抽象化して例外機構をユーザーに公開している。
追記
###デバッグモードに入る
statment にエラーが含まれているとエラーを検出しなくなるまでループさせる。
On Error GoTo ASSERT
statment
statment
statment
ASSERT:
If Err.Number Then
Debug.Print Err.Description
Err.Clear
Debug.Assert False ' スタックトレースへ
Resume 0 ' エラー行へ戻る
End If
ここでスタックトレースとは一行ずつ実行するあれのことである。
プロシージャ内のエラー行をvbaに選ばせるので行横に○をつける手間がない。
###デバッグ出力
ブック名とオブジェクト名を表示させると混乱しにくい。
"[" と "]" で囲むのはデバッグ用ラベルであることがわかるようにしている。
#Const DEBUG_MODE = True
#If DEBUG_MODE Then
Debug.Print "[" & ThisWorkbook.name & " " & Me.name & "]"
Debug.Print expression
Debug.Print "----- ----- ----- -----"
#End if