こんにちは! VBScriptの世界へようこそ。
Excelマクロの記録ボタンを押すだけの世界から一歩踏み出し、「システムとシステムを裏で繋ぐ」というエンジニアの醍醐味に触れようとしているあなたへ、今日はとてもワクワクするテーマをお持ちしました。
今回のミッションはズバリ、「VBScriptでREST APIを叩き、JSONデータを取得して業務に活かす」ことです。
「えっ、VBScriptって大昔のレガシーな言語でしょ? そんなモダンなWeb API連携なんてできるの?」と思ったそこのあなた。ふふ、侮るなかれ。Windows環境さえあれば、追加のインストールも一切不要で、この軽量なスクリプトエンジンが最強のAPIクライアントに化けるんです。
ここをクリアすれば、VBScriptの基礎だけでなく、HTTP通信の裏側やエラーハンドリングの本質までバッチリ理解できますよ。さあ、私と一緒に極限の知見に触れていきましょう!
—
1. なぜ今、VBScript × REST APIなのか?
業務の現場では、「特定のWebサービスから定期的にデータを取得してExcelやCSVにまとめたい」「社内のチャットツールに自動で通知を飛ばしたい」といった要望が絶えません。
本来ならPythonやNode.jsを使いたいところですが、セキュリティが厳格な社内端末では、勝手に新しいランタイムをインストールできない壁にぶつかります。そんな時、どのWindowsにも標準搭載されているVBScript (WSH)なら、情報システム部門の許可を得るまでもなく、即座に自動化スクリプトを稼働させることができます。
ここで使うのが、Windowsの秘儀 `MSXML2.ServerXMLHTTP` です。
—
2. 実装の全体像とアーキテクチャ
まずは、私たちがこれから書くスクリプトの全体像を頭に思い描いてみましょう。
[VBScript (WSH)]
│
├─ 1. HTTP通信の準備(URL、メソッド、タイムアウト設定)
├─ 2. リクエスト送信 (GET / POST)
│ ↓
│ [ 外部REST API / Webサーバー ]
│ ↓
├─ 3. レスポンス(JSON文字列)の回収
└─ 4. スクリプト制御によるデータ抽出(擬似パース)
VBScriptには標準でJSONをオブジェクトに変換するパーサー(`JSON.parse`のような機能)がありません。そのため、「文字列操作(正規表現や `InStr`、`Mid` 関数)」を駆使して必要なデータを切り出すという、少し泥臭い、しかしエンジニアとしての腕の見せ所となるテクニックを使います。
—
3. 実践!タイムアウト制御付きHTTP GET & JSON処理コード
百聞は一見にしかず。現場でそのままコピペして使える、極上の実用スクリプトを公開します。
今回は、ダミーのJSONを返すパブリックなAPI(JSONPlaceholder)を叩き、ユーザー情報を取得する例を見てみましょう。
デスクトップなどに `api_test.vbs` という名前で保存し、ダブルクリック(またはコマンドプロンプトから `cscript api_test.vbs`)で実行してみてください。
‘ =================================================================00
‘ 脚本名: RestApiIntegrationSample.vbs
‘ 概要: MSXML2.ServerXMLHTTPを用いた堅牢なREST API連携サンプル
‘ 執筆者: チーフアーキテクト
‘ =================================================================
Option Explicit
Sub Main()
Dim objHTTP
Dim strUrl
Dim lngTimeoutResolve, lngTimeoutConnect, lngTimeoutSend, lngTimeoutReceive
Dim strResponse
Dim lngStatus
‘ 1. 接続先URLの定義(今回はテスト用の公開APIを使用)
strUrl = “https://jsonplaceholder.typicode.com/users/1”
WScript.Echo “【INFO】APIリクエストを開始します…”
‘ 2. XMLHTTPオブジェクトの生成
‘ ※WinINetキャッシュやプロキシの問題を回避するため、ServerXMLHTTPを推奨
Set objHTTP = CreateObject(“MSXML2.ServerXMLHTTP.6.0”)
On Error Resume Next
‘ 3. タイムアウト設定の妙(ミリ秒単位)
‘ 引数の順番: 解決(Resolve), 接続(Connect), 送信(Send), 受信(Receive)
‘ これを設定しないと、APIが無応答のときにスクリプトが永遠にフリーズします(実務では必須!)
lngTimeoutResolve = 5000 ‘ 5秒
lngTimeoutConnect = 5000 ‘ 5秒
lngTimeoutSend = 5000 ‘ 5秒
lngTimeoutReceive = 10000’ 10秒
objHTTP.setTimeouts lngTimeoutResolve, lngTimeoutConnect, lngTimeoutSend, lngTimeoutReceive
If Err.Number <> 0 Then
WScript.Echo “【WARNING】タイムアウト設定に対応していないバージョンです: ” & Err.Description
Err.Clear
End If
‘ 4. HTTPリクエストのオープン (GETメソッド, 非同期=Falseで同期実行)
objHTTP.Open “GET”, strUrl, False
‘ 必要に応じてヘッダーを追加(APIの仕様に合わせて変更)
objHTTP.setRequestHeader “Content-Type”, “application/json”
objHTTP.setRequestHeader “User-Agent”, “VBScript-API-Client/1.0”
‘ 5. リクエスト送信
objHTTP.Send
If Err.Number <> 0 Then
WScript.Echo “【CRITICAL ERROR】通信エラーが発生しました: ” & Err.Description
Set objHTTP = Nothing
Exit Sub
End If
On Error Goto 0
‘ 6. ステータスコードの検証
lngStatus = objHTTP.status
If lngStatus = 200 Then
WScript.Echo “【SUCCESS】HTTP 200 OK! レスポンスを受信しました。”
strResponse = objHTTP.responseText
‘ 7. JSONレスポンスの擬似パースとデータ抽出
Call ParseAndShowData(strResponse)
Else
WScript.Echo “【ERROR】予期せぬステータスコードです: ” & lngStatus
WScript.Echo “レスポンス内容: ” & objHTTP.responseText
End If
‘ 8. オブジェクトの解放(メモリのクリーンアップ)
Set objHTTP = Nothing
WScript.Echo “【INFO】処理を正常に終了しました。”
End Sub
‘ —————————————————————–
‘ 関数名: ParseAndShowData
‘ 概要: 正規表現や文字列操作を用いて、JSONから特定の値を取り出す
‘ —————————————————————–
Sub ParseAndShowData(jsonText)
Dim userName, userEmail, userCity
WScript.Echo vbCrLf & “— [生JSONデータ] —”
WScript.Echo jsonText
WScript.Echo “———————-” & vbCrLf
‘ 【プロの知見】簡易JSON抽出ルーチン
‘ 本格的なパーサーを書く代わりに、VBScript標準の RegExp (正規表現) オブジェクトを使用します
Dim objRegExp, objMatches
Set objRegExp = New RegExp
objRegExp.Global = True
objRegExp.IgnoreCase = True
‘ name を抽出する正規表現 (“name”: “…”)
objRegExp.Pattern = “””name””\s:\s””([^””]+)”””
Set objMatches = objRegExp.Execute(jsonText)
If objMatches.Count > 0 Then
userName = objMatches(0).SubMatches(0)
Else
userName = “取得失敗”
End If
‘ email を抽出する正規表現
objRegExp.Pattern = “””email””\s:\s””([^””]+)”””
Set objMatches = objRegExp.Execute(jsonText)
If objMatches.Count > 0 Then
userEmail = objMatches(0).SubMatches(0)
Else
userEmail = “取得失敗”
End If
‘ ネストされたオブジェクト(address内のcityなど)の抽出も正規表現なら一撃です
objRegExp.Pattern = “””city””\s:\s””([^””]+)”””
Set objMatches = objRegExp.Execute(jsonText)
If objMatches.Count > 0 Then
userCity = objMatches(0).SubMatches(0)
Else
userCity = “取得失敗”
End If
‘ 結果を出力
WScript.Echo “【抽出結果】”
WScript.Echo ” – 氏名 (name) : ” & userName
WScript.Echo ” – getEmail : ” & userEmail
WScript.Echo ” – 都市 (city) : ” & userCity
Set objRegExp = Nothing
End Sub
‘ メイン処理の呼び出し
Main()
—
4. コードの深掘り:ここがエンジニアの腕の見せ所
上記のコードで、特に重要なポイントを3つ解説します。
① `ServerXMLHTTP` と `XMLHTTP` の違い
VBScriptでHTTP通信を行う際によく見かけるのが `MSXML2.XMLHTTP` ですが、私たちはあえて `MSXML2.ServerXMLHTTP.6.0` を採用しました。
なぜか? `XMLHTTP` は内部でInternet Explorer(WinINet)のキャッシュやセキュリティゾーン設定を引き継ぐため、サーバー環境やバックグラウンドのバッチ処理で予期せぬダイアログが表示されてフリーズする原因になります。一方、`ServerXMLHTTP` は完全にサーバーサイド(バックグラウンド)で動作するため、自動化スクリプトにはこちらが圧倒的に向いています。
② タイムアウト設定の絶対性
Web APIは相手がある話です。先方のサーバーが重かったり、ネットワークが切断されたりしたとき、タイムアウト設定をしていないスクリプトは「永遠に待ち続ける亡霊」と化します。
`objHTTP.setTimeouts` を使い、コネクションからデータ受信までの上限秒数を必ず指定するようにしましょう。これはプロのエンジニアとしての最低限のたしなみです。
③ VBScriptにおけるJSONパースの極意
前述の通り、VBScriptには標準のJSONライブラリがありません。無理にJScript(`eval`)を噛ませてパースする方法もありますが、セキュリティ(インジェクション脆弱性)の観点やコードの複雑化を考慮すると、必要なキー名が決まっている業務連携であれば、正規表現(`VBScript.RegExp`)でピンポイントに抜き出すのが最も安全でメンテしやすいという結論に達します。
—
5. 陥りやすい罠とエラーハンドリング
現場でこのスクリプトを動かすとき、よく遭遇するトラブルと対策をまとめました。
- エラー: 「プロキシサーバーの認証が必要」 / 「接続できません」
- 対策: 社内ネットワークから外部APIを叩く場合、プロキシの設定が必要な場合があります。`ServerXMLHTTP` はデフォルトでシステムのプロキシを無視することがあるため、必要に応じて `setProxy 2, “proxy.company.com:8080″` などの設定を追加してください。
- エラー: 「文字化けして日本語が読めない」
- 対策: APIのレスポンスヘッダーがUTF-8であっても、VBScriptの内部文字列処理で文字化けが起きることがあります。もし文字化けに悩んだら、レスポンスをバイナリ(`objHTTP.responseBody`)で受け取り、ADODB.Streamを使ってデコードする高度な手法にシフトしましょう。
—
おわりに
お疲れ様でした!
「VBScriptでREST APIを叩き、JSONを料理する」という一連の流れ、いかがでしたでしょうか。
一見レガシーに思えるVBScriptですが、このようにオブジェクトの特性を深く理解し、タイムアウトや正規表現によるパースといった適切な制御を組み込むことで、「モダンなWebサービスとシームレスに連携できる極めて強力な自動化ツール」へと生まれ変わります。
ここをクリアしたあなたなら、もうマクロの記録の枠を超えた、真の業務自動化エンジニアの扉を叩いています。自信を持って、日々の業務ハックにこの知見を役立ててくださいね! それでは、また次の極限の世界でお会いしましょう。
