LoginSignup
19
25

More than 5 years have passed since last update.

vbaのエラー処理

Last updated at Posted at 2015-01-29

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

19
25
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
25