以下の内容はhttps://error-daizenn.hatenablog.com/entry/2026/01/21/205424より取得しました。


VBAでWinAPIエラーコードを「番号→名前→意味」まで一気に辿る実践ガイド(FormatMessageとError名の取得法)

 

VBAでWinAPIエラーコードを「番号→名前→意味」まで一気に辿る実践ガイド(FormatMessageとError名の取得法)

WinAPIをVBAから呼び出すと、失敗時に「エラー番号(error code)」だけが返ってきて途方に暮れることがあります。0なら成功と分かっても、5や87、そして見慣れない5桁の数値が出た瞬間、調査コストが跳ね上がるのが現場のあるあるです。
この記事では、WinAPIのエラーコードを扱う基本(エラー番号・説明文・名前の違い)から、FormatMessageで説明文を得る方法、さらに「番号から ERROR_ACCESS_DENIED のような“エラー名”を返す」実装アイデア(Enum化モジュール方式)まで、VBA視点でまとめます。

WinAPIエラーコードの基礎:番号・説明文・名前は別物

WinAPIの多くは、戻り値で成功/失敗を返し、詳細は別途「最後のエラー」としてエラーコードが提供されます。VBAでは典型的に次のような情報が欲しくなります。

  • エラー番号:例)58715841

  • 説明文:例)「アクセスが拒否されました。」のような人間向け文言

  • エラー名:例)ERROR_ACCESS_DENIEDERROR_INVALID_PARAMETERERROR_API_UNAVAILABLE

説明文はユーザー表示に向きますが、開発者としては「エラー名」の方が検索性・分類・ログ分析に圧倒的に便利です。番号だけだと意図が読めず、説明文は曖昧だったり環境依存(ローカライズ)だったりします。一方、エラー名はログの“キー”として強い、というわけです。

説明文を取るならFormatMessageが王道

エラー番号から説明文を得たい場合、Windowsの FormatMessage を使うのが定番です。VBAでも宣言して呼べば、OSが持つメッセージテーブルから説明文を引いてくれます。

ポイントは次の通りです。

  • 取得できるのは基本的に説明文(ユーザー向けの文章)

  • 言語・OSバージョンに左右される可能性がある

  • ログ用途なら便利だが、「ERROR_~」の定数名は返ってこない

つまり「説明文だけで足りる」ケースには最適ですが、「番号→エラー名」が欲しいケースでは別の手段が必要です。

なぜ“エラー名”はそのまま取れないのか

WinAPIのエラー名は、C/C++のヘッダ(例:WinError.h)で #define ERROR_ACCESS_DENIED 5 のように定義されている“定数名”です。
OSのAPIが直接「名前」を返す仕組みは一般的ではなく、Windowsが返すのはあくまで数値と(必要なら)説明文です。そのため「番号→名前」をやるなら、結局どこかに 番号と名前の対応表 を持つ必要があります。

現実解:Enumに“ほぼ全エラー”を載せて逆引きする

実務で繰り返し調べるのが面倒なら、VBA側に「対応表」を持たせるのが最短です。考え方はシンプルで、次のような構成にします。

  • EnumERROR_SUCCESS = 0 のように、エラー名と番号を網羅的に定義

  • Public関数:番号を渡すと、該当するEnumメンバー名(文字列)を返す

  • 補助関数:VBEで「関数が大きすぎる」問題を回避するため分割

この方式のメリットは、ログに ERROR_INVALID_FUNCTION のような“意味のある文字列”を残せることです。番号のままより桁違いに読みやすく、説明文よりブレません。

実装イメージ(考え方の要点)

VBAで「値からEnum名」を直接取る仕組みはないため、実装では次のどれかを使います。

  • Select Case を自動生成して名前を返す(高速だが巨大化しやすい)

  • Enumの定義を使いつつ、内部で対応表(配列/Dictionary)を持つ

  • コード生成(外部で一覧を作り、モジュールに貼り込む)で保守

記事中の例のように「モジュール(.bas)をインポートして使う」設計は、配布と導入が簡単で、プロジェクト間の使い回しにも向きます。

使い方の流れ:VBAプロジェクトに組み込む

現場での運用は次の順で固めるとスムーズです。

  1. エラー名を逆引きするモジュール(.bas)をVBAプロジェクトにインポート

  2. WinAPI呼び出し後に得られたエラー番号を、公開関数へ渡す

  3. 返ってきた「エラー名」をログ・例外メッセージ・診断出力に使う

  4. 必要なら FormatMessage で説明文も併記し、ユーザー向け文面を整える

ログ例としては「番号+名前+説明文」の3点セットが強力です。
障害調査ではまず名前で当たりを付け、必要に応じて説明文で補足する運用が最短距離になります。

「obsolete(廃止)」コードが含まれる点に注意

Microsoftのエラーコード一覧には「obsolete」とされるものが混ざります。Enumを“全網羅”しようとすると、次の判断が必要です。

  • 今も発生しうるか(古いAPIのみ、互換性目的、など)

  • 定義しておく価値があるか(ログ解析の互換性重視なら残す)

  • 保守コスト(無理に完全一致を目指さず「主要なもの優先」も現実的)

実際には「頻出(アクセス拒否、引数不正、見つからない、権限、共有違反など)」を厚めにし、残りは段階的に追加する設計が破綻しにくいです。

開発者目線のおすすめ:ログは“人間が検索できる形”に寄せる

WinAPI連携の不具合は、再現が難しいほどログ品質がものを言います。おすすめは次の形です。

  • ログキー:エラー名(例:ERROR_ACCESS_DENIED

  • 補助情報:エラー番号(例:5

  • 表示文:FormatMessageの説明文(例:アクセスが拒否されました)

こうしておくと、コードレビューでも運用でも「読む→検索する→直す」が速くなります。

まとめ:番号だけの時代を終わらせる

WinAPIのエラーコードは膨大で、手作業の参照はすぐに限界が来ます。
説明文は FormatMessage で取れる一方、エラー名は対応表を持たない限り得られません。だからこそ、Enumと逆引き関数をモジュール化してプロジェクトに組み込み、「番号→名前」を即座に返せる状態を作るのが、VBAでWinAPIを扱う上での最短の投資対効果になります。

必要なときに、必要な形(ユーザー向け/開発者向け)でエラー情報を出せるようにしておく――それだけで、WinAPI連携のトラブルシューティングは一段ラクになります。




以上の内容はhttps://error-daizenn.hatenablog.com/entry/2026/01/21/205424より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14