2014年6月29日日曜日

[MS Access] SQLのユーザ定義関数で Err.Raise しても捕まえられない

Microsoft Access で、SQLのユーザ定義関数の中でランタイム エラーを生成する場合は、Err.Raise メソッドではSQLを実行した側でエラー処理ルーチン (On Error GoTo) で捕まえることができない。

ランタイム エラーを捕まえられないと、VBAのエラーダイアログが表示されてしまう。SQLの中で発生したランタイム エラーを捕まえるには、CVErr関数でユーザー指定のエラーを戻すことになります。ただし欠点があり、関数戻り値のデータ型をVariant型に変更する必要があります。Variant型で数値を戻すと、SQL中では文字列として扱われるので厄介なのです。

1.ランタイム エラーを捕まえられないケース

Public Function Func1(Value As Integer) As Integer
  Err.Raise Number:=100, Source:="UserDefined", Description:="メッセージ"
  Func1 = Value
End Function

Sub Test1()
  On Error GoTo ErrorHandler
  Call CurrentDb.OpenRecordset("SELECT Func1(123)")
  Exit Sub

ErrorHandler:
  ' ここには到達できない。
  Debug.Print Err.Number & vbTab & Err.Source & vbTab & Err.Description
End Sub


2.CVErr関数の戻り値を返すケース

Public Function Func2(Value As Integer) As Variant
  Func2 = CVErr(100)
End Function

Sub Test2()
  On Error GoTo ErrorHandler
  Call CurrentDb.OpenRecordset("SELECT Func2(123)")
  Exit Sub

ErrorHandler:
  ' ここを通ることができる。
  Debug.Print Err.Number & vbTab & Err.Source & vbTab & Err.Description
End Sub