4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VBAでAPI呼び出し時のエラー番号をFormatMessageを使って、エラーメッセージに変換する。

Last updated at Posted at 2018-05-28

VBAでAPIを呼び出した場合の Err.LastDllErrorを FormatMessageを使って、エラーメッセージに変換します。
持てる限りの力技を使ってみました。
FormatMessageにより、メッセージ文字列のポインタが渡されるので、これをSysAllocStringを使って、BSTRに複写したうえで、VBAの文字列型変数に割り当てます。

Private Declare PtrSafe Function FormatMessage Lib "Kernel32.dll" Alias "FormatMessageW" ( _
    ByVal dwFlags As Long, _
    ByVal lpSource As LongPtr, _
    ByVal dwMessageId As Long, _
    ByVal dwLanguageId As Long, _
    ByVal lpBuffer As LongPtr, _
    ByVal nSize As Long, _
    ByVal Arguments As LongPtr) As Long
     
Private Declare PtrSafe Sub RtlMoveMemory Lib "kernel32" ( _
    ByVal Destination As LongPtr, ByVal Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function SysAllocString Lib "OleAut32.dll" (ByVal psz As LongPtr) As LongPtr
Private Declare PtrSafe Function LocalFree Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr

Function GetApiErrorText(ByVal Code As Long) As String
    Const FORMAT_MESSAGE_ALLOCATE_BUFFER As Long = &H100&
    Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000&
    Const FORMAT_MESSAGE_IGNORE_INSERTS As Long = &H200&
    'MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)の計算済みの値を宣言
    Const MAKELANGID_LANG_NEUTRAL_SUBLANG_DEFAULT As Long = &H400
    Dim lpMsgBuf As LongPtr
    
    
    FormatMessage _
        FORMAT_MESSAGE_ALLOCATE_BUFFER Or _
        FORMAT_MESSAGE_FROM_SYSTEM Or _
        FORMAT_MESSAGE_IGNORE_INSERTS, _
        0, _
        Code, _
        MAKELANGID_LANG_NEUTRAL_SUBLANG_DEFAULT, _
        VarPtr(lpMsgBuf), _
        0, _
        0
                  
    Dim lpNewString As LongPtr
    GetApiErrorText = vbNullString
    lpNewString = SysAllocString(lpMsgBuf)
    LocalFree lpMsgBuf
    RtlMoveMemory VarPtr(GetApiErrorText), VarPtr(lpNewString), LenB(lpNewString)
   
End Function

使い方の例です。

Sub Main()
    ' Err.LastDllError を引数に代入するのが本来の使い方ですが
    ' ここで代わりに1を代入します。
    Debug.Print GetApiErrorText(1)
End Sub
4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?