Excel VBAだけで、非同期HTTPクライアントとローカル簡易HTTPサーバーを動かし、通信の両側をTraceIdで追跡する学習用サンプルです。
外部のPowerShell、curl、Webサービス、APIキーは使いません。クライアントとサーバーを自分のPC内で動かすため、HTTPの要求・応答、非同期イベント、エラー処理を段階的に観察できます。
対象: Windows版Excel / VBA7(32ビット版・64ビット版Office)
用途: 初学者、学生、社内研修、VBAからREST APIを呼び出す前の基礎学習
注意: このサーバーは教材です。業務用・公開用Webサーバーとしては使用できません。
- 同期通信と非同期通信の違い
MSXML2.XMLHTTP60のreadyStateとイベント駆動- HTTPのリクエスト行、ヘッダー、本文、ステータスコード
- TCPの
socket、bind、listen、accept、recv、send - VBAのUnicode文字列とHTTPのUTF-8バイト列の違い
Content-Lengthが「文字数」ではなく「バイト数」である理由- クライアントとサーバーを同じTraceIdで追跡する方法
- HTTP 500、接続失敗、遅延、キャンセルの観察
- 秘密情報をトレースへ残さない設計の考え方
sequenceDiagram
participant C as Client.xlsm
participant S as Server.xlsm
C->>S: HTTP要求 + X-Trace-Id
Note over C: Send後すぐExcelへ制御を戻す
S->>S: 解析・ルート処理
S-->>C: HTTP応答 + 同じX-Trace-Id
Note over C,S: 両方のTraceシートを照合
推奨構成は、1冊のマクロブックへ全5モジュールを取り込み、マクロから同じブックを別Excelプロセスで読み取り専用として開く方法です。
| Excelプロセス | ブック | 役割 |
|---|---|---|
| 元のExcel | VBA_Async_HTTP_API_Sample.xlsm |
非同期クライアントを実行 |
| 自動起動したExcel | 同じブックの読み取り専用コピー | 127.0.0.1:18080で簡易HTTPサーバーを実行 |
/delay?ms=3000を使うと、サーバー側が約3秒待機している間もクライアント側Excelを操作できます。これが非同期通信を体験する最も分かりやすいサンプルです。
VBA_Async_HTTP_API_Sample/
├─ README.md
├─ SECURITY.md
├─ src/
│ ├─ CAsyncHttpClient.cls 非同期HTTPクライアント
│ ├─ modClientDemo.bas クライアント用の実行マクロ
│ ├─ modHttpServer.bas Winsock簡易HTTPサーバー
│ ├─ modTrace.bas Traceシートへの共通記録
│ └─ modUtf8.bas Unicode/UTF-8変換
└─ docs/
├─ TESTING.md テスト手順と期待結果
└─ REVIEW.md 疑似ペルソナ100回の静的レビュー記録
- Windows版Excelを起動します。
- 新しいブックを
VBA_Async_HTTP_API_Sample.xlsmとして保存します。 Alt+F11でVBE(Visual Basic Editor)を開きます。ツール→参照設定で、Microsoft XML, v6.0にチェックを付けます。ファイル→ファイルのインポートで、次の5ファイルをすべて読み込みます。src/modTrace.bassrc/modUtf8.bassrc/modHttpServer.bassrc/CAsyncHttpClient.clssrc/modClientDemo.bas
デバッグ→VBAProjectのコンパイルを実行します。- ブックを保存します。
元のブックでServer_StartInNewExcelを実行します。
このマクロは次を自動で行います。
CreateObject("Excel.Application")で別Excelプロセスを作る。- 保存済みの同じ
.xlsmを読み取り専用で開く。 - サーバー側のTraceシートを初期化する。
- サーバー側コピーで
Server_Startを実行する。
Shell、PowerShell、curlは使いません。別のExcelウィンドウが開き、そのTraceシートにLISTEN / READYが表示されれば起動完了です。
マクロを許可できない場所から開いた場合や、組織ポリシーで自動化されたブックのマクロが禁止されている場合は起動できません。セキュリティ設定を回避せず、信頼できる場所と組織の規則を確認してください。
元のExcelへ戻り、Client_Helloを実行します。元ブックのTraceシートでREADY_STATEとHTTP 200を確認します。
サーバーは127.0.0.1:18080だけで待ち受けます。127.0.0.1はループバックアドレスで、同じPC自身を表します。
元のブックでServer_StopInNewExcelを実行します。サーバーへ停止を依頼し、読み取り専用コピーを保存せず閉じ、サーバー用Excelプロセスも終了します。
Client_ShutdownServerはHTTPの/shutdownを学ぶためのマクロです。待受けは停止しますが、Traceを観察できるようサーバー用Excelウィンドウは残ります。観察後にServer_StopInNewExcelを実行してください。
手動で2つのブックへ分ける方法も利用できます。その場合は、サーバー用ブックへmodTrace、modUtf8、modHttpServerを、クライアント用ブックへmodTrace、CAsyncHttpClient、modClientDemoを取り込みます。
| メソッド | URL | 学習内容 | 主な応答 |
|---|---|---|---|
| GET | /hello |
最小の要求・応答 | HTTP 200 + 固定JSON |
| POST | /echo |
本文とContent-Length | 送った本文をそのまま返す |
| GET | /delay?ms=3000 |
非同期と待機 | 指定時間後にHTTP 200 |
| GET | /status/500 |
HTTPエラー | 意図的なHTTP 500 |
| POST | /shutdown |
後始末 | 応答後にサーバー停止 |
msは0~10000ミリ秒に制限しています。数値でない場合は1000ミリ秒になります。
| マクロ | 動作 |
|---|---|
Client_Hello |
/helloを呼ぶ |
Client_Echo |
JSONを/echoへPOSTする |
Client_Delay3Seconds |
3秒遅延を試す |
Client_Status500 |
HTTP 500を観察する |
Client_RunBasicSequence |
3要求を連続開始する |
Client_CancelAll |
実行中の要求を中止する |
Client_ShutdownServer |
サーバーを遠隔停止する |
Server_StartInNewExcel |
同じブックを別Excelプロセスで開き、サーバーを開始する |
Server_StopInNewExcel |
自動起動したサーバーとExcelプロセスを終了する |
Server_Start |
待受けを開始する |
Server_Stop |
待受けとWinsockを終了する |
Trace_Clear |
Traceシートを初期化する |
Traceシートには次の列を作ります。
| 列 | 意味 |
|---|---|
| 日時 | ミリ秒付きの記録時刻 |
| TraceId | 1つの要求を結び付ける識別子 |
| 側 | CLIENTまたはSERVER |
| 処理段階 | SEND、RECEIVE、PARSEなど |
| 方向 | OUT、IN、LOCAL |
| 詳細 | URL、受信バイト数、応答本文など |
| 結果 | OK、WAITING、HTTP 500など |
| 経過時間(ms) | 要求開始または接続受付からの時間 |
たとえば/echoでは、概ね次の順番になります。
CLIENT CREATE LOCAL POST /echo
CLIENT READY_STATE IN OPENED
CLIENT SEND OUT 本文文字数=...
SERVER ACCEPT IN クライアント接続を受付
SERVER RECEIVE IN 受信=...バイト
SERVER PARSE LOCAL POST /echo
SERVER RESPONSE OUT HTTP 200
CLIENT READY_STATE IN HEADERS_RECEIVED
CLIENT READY_STATE IN LOADING
CLIENT READY_STATE IN DONE
CLIENT TRACE_ID IN MATCH
CLIENT RESPONSE IN HTTP 200の本文
CLIENT COMPLETE LOCAL OK
クライアントのX-Trace-Id要求ヘッダーをサーバーが読み、同じ値を応答ヘッダーにも付けます。クライアントは応答値を照合し、TRACE_ID / MATCHを記録します。2冊のTraceシートをTraceIdで絞り込むと、1要求だけを追跡できます。
A~G列は文字列形式、経過時間のH列は数値形式です。値はValue2で書き込み、同じ内容をVBEのイミディエイトウィンドウへもDebug.Printで出力します。
| 値 | 名前 | 意味 |
|---|---|---|
| 0 | UNSENT | まだ初期化されていない |
| 1 | OPENED | Openが完了した |
| 2 | HEADERS_RECEIVED | HTTP応答ヘッダーを受信した |
| 3 | LOADING | 応答本文を受信中 |
| 4 | DONE | 通信処理が完了した |
HTTP 500でもreadyStateは4になります。DONEは「HTTP処理の成功」ではなく「通信処理が完了した」という意味です。そのため、完了後にStatusも必ず確認します。
XMLHTTP60のonreadystatechangeを受け取るには、WithEventsをクラスモジュール内で宣言します。
Private WithEvents m_http As MSXML2.XMLHTTP60さらに、非同期要求を開始したSubが終わってもクラスが破棄されないよう、modClientDemoのCollectionへ保持します。完了後はCollectionから取り除きます。
WSAStartup
↓
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
↓
bind(127.0.0.1:18080)
↓
listen
↓
accept
↓
recv(ヘッダー末尾とContent-Lengthまで)
↓
HTTP解析・ルート処理
↓
send(全バイトを送るまで繰り返す)
↓
closesocket
待受けと受信には非ブロッキングソケットを使い、Application.OnTimeで約1秒ごとに確認します。したがって、この教材の応答時間には最大約1~2秒程度のポーリング待ちが加わる場合があります。
- API宣言には
PtrSafeを付けています。 - ソケットハンドルには
LongPtrを使っています。 - バイト数、ポート番号、エラーコードには
Longを使っています。 - Windows SDKに合わせ、
WSADATAのフィールド順を#If Win64 Thenで分けています。
対象はVBA7です。Office 2010以降のWindows版Excelが目安ですが、実際の利用可否はMicrosoft XML 6.0とWindows APIの提供状況にも依存します。
ソースはGitHub上で読みやすいUTF-8です。一方、VBEの「ファイルのインポート」は、Officeの版やWindowsの言語設定によってUTF-8の日本語コメントを正しく解釈しない場合があります。
文字化けした場合は、次のどちらかで対応してください。
- GitHubのRaw表示からコードをコピーし、VBEの新規モジュールへ貼り付ける。
- ソースをWindowsの日本語ANSI(CP932 / Shift_JIS)へ変換してからインポートする。
プロシージャ名や変数名はASCIIで統一しているため、コメントが文字化けしても構文への影響を抑えています。ただし日本語文字列リテラルも含むため、コンパイル前に表示を確認してください。
- Windows版Excel専用です。Mac版ExcelではWinsock APIを利用できません。
- TLS(HTTPS)サーバー機能はありません。通信先はローカルのHTTPだけです。
- 1接続ずつ処理します。同時多数接続には対応しません。
- Chunked Transfer Encoding、Keep-Alive、HTTP/2には対応しません。
- 要求サイズ上限は65536バイトです。
/delayはサーバー側Excelプロセスを指定時間だけ停止します。Application.OnTimeのため、高精度な性能測定には使えません。.xlsmは収録していません。VBAソースを自分で取り込む教材形式です。
MSXML2.XMLHTTP60の参照設定が不足しています。クライアント用ブックでMicrosoft XML, v6.0を有効にしてください。
通常は、同じポートを別プロセスが使用中です。既に起動中のServer.xlsmがないか確認し、終了後に再実行してください。
HTTP応答を受け取る前に接続が失敗しています。サーバーがLISTEN / READYになっているか、URLとポートが一致しているか確認してください。
サーバーは約1秒間隔でポーリングします。教材として処理段階を観察しやすくする構成であり、高速Webサーバーではありません。
ファイルを信頼できる場所へ置き、Windowsのファイルプロパティに「許可する」があれば内容を確認したうえで設定してください。出所が不明なマクロは実行しないでください。
ソース構造、API宣言の32/64ビット方針、エンドポイント分岐、秘密情報のマスキング、後始末、READMEとの対応を静的に確認しています。現在の作成環境にはWindows版Excel/VBEがないため、実機でのコンパイルと通信試験は未実施です。
実機確認では、必ずテスト手順に沿ってVBAProjectのコンパイルから始めてください。実機差が見つかった場合は、Officeのビット数、Excelのバージョン、Windowsのバージョン、Traceシート、エラー番号を添えて報告してください。
ローカル教材であっても、マクロとネットワーク処理には注意が必要です。SECURITY.mdを先に確認してください。
本リポジトリは、Excel VBAからWindowsのネットワーク機能を学ぶ教材シリーズの一つです。HTTPの前段となるTCP/UDP、名前解決を扱うDNS、到達性と経路を調べるPing/Tracerouteも公開しています。
シリーズの一覧と推奨学習順序は、papanda925 GitHubプロフィールを参照してください。技術記事はpapanda925.comで公開しています。
この教材はMIT Licenseで公開しています。学習、授業、社内研修、改変、再配布に利用できます。再利用する場合は、著作権表示とライセンス文を残してください。ソフトウェアは無保証です。