弊社でMicrosoft Accessのアプリケーションを開発する際、よく使う機能はライブラリデータベースを準備してそこにコードを記述するようにしています。
アプリケーションデータベース(以降、アプリ)からは、ライブラリデータベース(以降、ライブラリ)を参照設定して使用することになります。
今回、あるお客様のライブラリ側の機能を見直しを行い、エラーが発生した際のアプリ側への通知をリターンコードではなくErrオブジェクトで行うようにしました。
Dim lngErrNumber As Long Dim strErrDescript As String : On Error GoTo Catch : Catch: lngErrNumber = Err.Number strErrDescript = Err.Description On Error GoTo 0 Select Case lngErrNumber Case 70 ' 書き込みできません Err.Raise 1001, "ファイルが開かれています。" & vbNewLine & vbNewLine _ & "ファイルを閉じてから再実行してください。" Case Else Err.Raise lngErrNumber, strErrDescript End Select
アプリ側でテストしてみると、エラーメッセージが意図したものではなく掲題の『アプリケーション定義またはオブジェクト定義のエラーです』になります。
エラーコードは『1001』になっていますので、メッセージだけの問題のようです。
『アプリケーション定義またはオブジェクト定義のエラーです』は、エラーコードに該当するメッセージが見つからないときの既定のメッセージということですので、参照設定しているとはいえデータベースが異なるとエラーメッセージは引き継がれないのか…等々、考えたわけです。
初心に戻って(←ここ大切です)、ライブラリ側だけでテストしてみると、ライブラリ側でも『アプリケーション定義またはオブジェクト定義のエラーです』になります。
ここにいたってようやくErr.Raiseが正しく機能していないことに気づき、よく見てみると
' 間違い Err.Raise 1001, "ファイルが開かれています。" & vbNewLine & vbNewLine _ & "ファイルを閉じてから再実行してください。" ' 正しい Err.Raise 1001, , "ファイルが開かれています。" & vbNewLine & vbNewLine _ & "ファイルを閉じてから再実行してください。"
ということで、カンマが一つ抜けていたため、引数の位置渡しでDescriptionにエラーメッセージを記述したつもりがSourceに記述していたというお粗末な間違いでした。
位置渡しではなく、
Err.Raise Number:=1001 _ Description:="ファイルが開かれています。" & vbNewLine & vbNewLine _ & "ファイルを閉じてから再実行してください。"
のように名前渡しで記述すれば、このようなミスもなく引数の意味も明示できるのですが、VBAのコードエディタは名前渡しのインテリセンスが効かないため、名前渡しにすると生産効率が落ちてしまいますし、引数の意味が明示できていなくとも大体のところはわかるということで、位置渡しで記述しています。
そのため、たまにこのようなエラーに悩まされ生産効率に影響が出てしまうのですが、トータルで考えれば位置渡しでも問題ないかと😅
ということで、お粗末な間違いのお話でした。
コメント