すすベン : エラー図鑑#2 ExcelVBA 440

まえおき

めっちゃ久しぶりの更新です…。
ExcelVBA(以下、VBA)を触っていたところ、とあるエラーの解決法が見つからず、最終的に海外サイトでようやく発見したので忘れぬ内に記録しておきます。

Err.Raiseしたエラー番号が書き換わる…?

エラーに遭遇した状況はこんな感じ。
VBAにてエラーハンドリング処理を追加していた時のこと。ユーザー定義エラーのエラー番号に777(仮)を指定したはずが、身に覚えのないメッセージが表示されました。

上記の状況を簡略化したコードがこちら。

まずは作成したクラスモジュール。ステップインで確認すると、問題なのはコンストラクタだけということが分かったのでその部分のみ。

Option Explicit

Sub Class_Initialize()
On Error GoTo HandleErr

    ' 初期化処理

    Err.Raise Number:=777, Description:="ユーザー定義エラー発生"
    
HandleErr:
    
    ' エラー処理
    
    Err.Raise Err.Number ' mainにエラーを伝える

End Sub

そしてメインのSubプロシージャ。

Sub main()
On Error GoTo HandleErr

    Dim tmpClass As ExampleClass
    Set tmpClass = New ExampleClass
    
    ' tmpClassで色々する
    
HandleErr:
    
    MsgBox Err.Number & vbCrLf & Err.Description
    
End Sub

で、mainを実行した結果表示されたメッセージがこちら。Err.Raise時に設定したはずの内容とは違うものとなってしまいました。

簡潔っ…!

何はともあれ公式ドキュメント

エラー番号440についてMicrosoftの公式ドキュメントで調べてみました。

オートメーション オブジェクトにアクセスするときに、特定の種類のエラーが発生する可能性があります。 このエラーの考えられる原因と解決策を次に示します。

メソッドを実行しているときか、オブジェクト変数のプロパティを取得または設定しているときに、エラーが発生しました。 エラーは、オブジェクトを作成したアプリケーションによって報告されました。

Err オブジェクトのプロパティを確認し、エラーの原因と性質を特定します。 また、アクセス元のステートメントの直前で On Error Resume Next ステートメントを使用して、アクセス元のステートメントの直後でエラーがないかどうかを確認します。

Office VBA リファレンス: オートメーション エラーです (エラー 440)
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/automation-error-error-440

正直よく分かりませんでした。…力不足。
他にも調べてみた感じ、結構いろんな状況で起きるらしい。
公式ドキュメントは自分で調べろって言ってるみたい…?

結論:Class_Initialize()内でErr.Raiseしない

調べた結果、コンストラクタ内でErr.Raiseしようとするとユーザー定義のエラー番号が上手く伝播しないことが分かりました。

この現象はコンストラクタの内容をそのまま通常のクラスプロシージャとして記述することで回避できるようです。

さっきのクラスモジュールをこんな感じに書き換えます。mainはそのままでOK。

Option Explicit

Sub Class_Initialize()

    classInitialize

End Sub

Sub classInitialize()
On Error GoTo HandleErr

    ' 初期化処理

    Err.Raise Number:=777, Description:="ユーザー定義エラー発生"
    
HandleErr:
    
    ' エラー処理
    
    Err.Raise Err.Number ' mainにエラーを伝える

End Sub

上記コードでmainを実行した結果がこちら。

想定通りになりました

あとがき

以上、エラーハンドリングしていて突っかかった現象を解決する方法の記録でした。
同じ状況についての日本語記事が無かったので解決まで大分苦戦しました…。英語検索をもっと気軽に出来るようになりたいところ。

ここまでお読みいただきありがとうございました。
少しでも、同じ現象に遭遇している誰かのお役に立てていれば幸いです。

参考

Office VBA リファレンス:オートメーション エラーです (エラー 440)
(2021年7月29日閲覧)
VBA raising errors from within Class modules (with Class_Initialize) fails
(2021年7月29日閲覧)