「マイクロソフトがそう言った」を超えるレベルがあります。発生するエラー番号は 32 ビット整数です。これは、コンポーネント間でエラーを渡すための COM 仕様の一部であるためです。コンポーネントのすべてのパブリック メソッドは、実際には戻り値として HRESULT を返す関数です。VB 関数がある場合、関数の戻り値を秘密裏に [out] パラメータにマップします。HRESULT 値は、値のヒープ全体で構成されるビットフィールドです。ただし、単純にするために、2 つの 16 ビット部分に分割できます。下位 16 ビットには実際のエラー番号が含まれており、0 から 65535 (符号なし 16 ビットの範囲) の間になります。上位 16 ビットには多くの規格があります。最も重要なのは 0x0000____ です。これを使用するすべての定数は "S_" (成功の略) で始まります。最も一般的に使用される 32 ビット値は S_OK (0x00000000) です。この値が返された場合、関数は成功しています。ほとんどの VB メソッド呼び出しは、この値を返します。ただし、最上位ビットが設定されている値は、エラーが発生したことを示します。16 進数では、これらは 0x8___ のような値です。エラーには多くのクラスがあります。VB がデフォルトで返すものは 0x800A です。ただし、COM 仕様では、公式に使用できるクラスは 0x8004 のみです。これは、VB では定数 vbObjectError として表されます。
実際、VB では、ActiveX DLL または EXE のパブリック メソッドでエラーが発生する場合は、vbObjectError 定数を使用することをお勧めしています。やるかやらないかは関係ありません。これは、呼び出し元のコードが受け取ったエラーが非常に大きく負であることを意味するだけなので、エラー番号と &H0000FFFF の AND をとって 16 ビット整数を取得する必要があります。興味深いことに、それはまた、あなたがしないことをお勧めしますおそらく、ActiveX コントロール メソッドに関連付けられている上位 16 ビットが 0x800A000 であるためです。さらに興味深いことに、VB 自体は、デフォルトでエラー番号を上げると、すべてのエラー番号と 0x800A0000 の AND をとります。同様に、エラー番号が 0x800A____ のようなものであるかどうかを検出します。そうであれば、とにかく上位 16 ビットを削除するので、エラー番号自体を処理するだけです。私の職場には、多くの VB コンポーネントがあります。私たちの標準は、エラー コードと vbObjectError の論理和をとらないことです。これにより、後で呼び出しコードでそれをマスクする必要がなくなります。
たとえば、COMPONENT1.CLASS1 と COMPONENT2.CLASS2 があるとします。CLASS1.Method1 は CLASS2.Method1 を呼び出します。CLASS2 でエラーが発生した場合は、CLASS1.Method1 で処理する必要があります。Microsoft の指示に従って、次のように記述します。
COMPONENT1.CLASS1
Function Method1()
On Error GoTo ErrorHandler
...
ErrorHandler:
If (Err.Number And vbObjectError) = vbObjectError Then
Select Case Err.Number And (Not vbObjectError)
Case Component2.EErrComponent2.ecBlahBlahError
... handle ...
End Select
End If
End Function
COMPONENT2.CLASS2
Enum EErrComponent2
ecBlahBlahError = 513 ' Minimum error code
End Enum
Function Method1()
...
Err.Raise EErrComponent1 Or vbObjectError
...
End Function
複数のコンポーネントに対してこれを繰り返します。このボイラープレートは少し面倒で、実際には何も見返りがないようです。
おそらくこれを行うでしょう:
COMPONENT1.CLASS1
Function Method1()
On Error GoTo ErrorHandler
...
ErrorHandler:
Select Case Err.Number
Case Component2.EErrComponent2.ecBlahBlahError
... handle ...
End Select
End Function
COMPONENT2.CLASS2 Enum EErrComponent2 ecBlahBlahError End Enum
Function Method1()
...
Err.Raise EErrComponent1
...
End Function
vbObjectError を使用していないときに問題が発生したことがある人はいないでしょうか。確かにそうではありません。