Errオブジェクトをラップしたクラス
Errオブジェクトをラップしたクラス
このとき、ErrObject
クラスはインスタンス化できないことを示した。
よく「Err
オブジェクト」という表現も見かけるが、
Set hoge = New Err
という書き方ができるわけでもない。
ただ、イミディエイト・ウインドウで
?TypeName(Err)
と書いて[Enter]を押すと、ErrObject
が返る。
……ということは、よく使うErr
というやつは、ErrObject
クラスの唯一のインスタンスなのか……???
この辺はよくわからん。
とにかく、エラーが出たときに、そのエラーそのものを外に投げられたらいいのに、と思ったので、Err
オブジェクトをラップしたクラスを作ってみた。
ErrorObjectクラス
「Error
」も「ErrObject
」も既に使われているオブジェクト名なので、オブジェクト名は「ErrorObject
」にした。うーん、イマイチ。
ちなみに、Attribute VB_PredeclaredId = True
にしている。
クラスモジュール ErrorObject
Option Explicit '///Attribute VB_PredeclaredId = True///' Private number_ As Long Private description_ As String Private lastDllError_ As Long Private source_ As String Public Property Get Number() As Long Number = number_ End Property Public Property Let Number(ByVal value_ As Long) number_ = value_ End Property Public Property Get Description() As String Description = description_ End Property Public Property Let Description(ByVal value_ As String) description_ = value_ End Property Public Property Get LastDllError() As Long LastDllError = lastDllError_ End Property Public Property Let LastDllError(ByVal value_ As Long) lastDllError_ = value_ End Property Public Property Get Source() As String Source = source_ End Property Public Property Let Source(ByVal value_ As String) source_ = value_ End Property Public Sub clearError() number_ = 0 description_ = "" lastDllError_ = 0 source_ = "" Call Err.Clear End Sub Public Sub raiseError( _ Optional ByVal number__ As Long, _ Optional ByVal source__ As Long, _ Optional ByVal description__ As String) If number__ > 0 Then number_ = number__ If source__ > 0 Then source_ = source__ If description__ <> "" Then description_ = description__ If number_ = 0 Then Exit Sub Call Err.Raise(number_, source_, description_) End Sub Public Function getInstance( _ ByVal number__ As Long, _ Optional ByVal description__ As String, _ Optional ByVal source__ As String, _ Optional ByVal lastDllError__ As Long) As ErrorObject Dim ret As New ErrorObject ret.Number = number__ ret.Description = description__ ret.Source = source__ ret.LastDllError = lastDllError__ Set getInstance = ret End Function
ホントにただErr
オブジェクトをラップしただけ。getInstance
メソッドでインスタンスを吐くようにしたけれど、意味があるのかどうなのかわからない。
使ってみる
標準モジュールに次のようなコードを書いて実験。
リスト1 標準モジュール
Option Explicit Private ret As ErrorObject Private errorSource As String Public Sub test() Dim result As ErrorObject Set result = aCertainProcess With result Debug.Print "Number:" & .Number Debug.Print "Description:" & .Description Debug.Print "Source:" & .Source Debug.Print "LastDLLError:" & .LastDllError End With End Sub Private Function aCertainProcess() As ErrorObject On Error Resume Next Call process1 If Err.Number > 0 Then _ errorSource = "手順1": GoTo ErrorHandler Call process2 If Err.Number > 0 Then _ errorSource = "手順2": GoTo ErrorHandler Call process3 If Err.Number > 0 Then _ errorSource = "手順3": GoTo ErrorHandler ErrorHandler: Set ret = ErrorObject.getInstance( _ Err.Number, Err.Description, errorSource, Err.LastDllError) Call Err.Clear Set aCertainProcess = ret Set ret = Nothing End Function Private Sub process1() End Sub Private Sub process2() End Sub Private Sub process3() Call Err.Raise(5) End Sub
aCertainProcess
メソッドの返り値をErrorObject
型にしている。
aCertainProcess
からは、process1
、process2
、process3
の各メソッドを呼び出す。process1
、process2
では何も起きないが、process3
メソッドを実行すると、エラー番号「5
」の実行時エラーが起きる。
aCertainProcess
メソッドでは、process1
、process2
、process3
の各メソッドを実行するごとにErr.Number
プロパティを調べ、「0」を超える数値が返ったら、すなわちエラーが起きていたら、変数errorSource
に処理の場所を表す文字列をセットして、ErrorHandler
ラベルに飛ぶ。
ErrorHandler
ラベル以下では、そのときのErr
オブジェクトの状態を転写したErrorObject
クラスのインスタンスを作成してreturn。
呼び出し元のtest
プロシージャでは、返り値であるErrorObject
クラスのインスタンスが持っている諸データをイミディエイトに出力する。
実行結果
実行後のイミディエイト・ウインドウが
これ。
おわりに
まあ、これぐらいのことなら別に構造体でいいよな。