概要
Utf8BytesとUtf8Decodeは、Excel VBAから日本語を含むWeb API通信を行うための汎用プロシージャです。
VBAの文字列をそのままCOM通信へ渡すと文字化けすることがあるため、送信前にUTF-8バイト配列へ変換し、応答もUTF-8として復元します。
使う場面
- VBAからGASや外部Web APIへ日本語を含む本文をPOSTする
http.responseBodyを文字化けさせずに読みたいMSXML2.ServerXMLHTTP.6.0と組み合わせて通信処理を作る- テキストの入出力をUTF-8にそろえたい
使用例
Dim payload As Variant
Dim result As String
payload = Utf8Bytes("日本語を含む送信本文")
http.send payload
result = Utf8Decode(http.responseBody)
payloadはByte()ではなくVariantで受けてからCOMへ渡します。
詳しくはVBAでCOMに配列を渡すときはVariantで受けるを参照してください。
コピー可能な実装コード
コードを読み込み中...初心者向けコード解説
ADODB.Streamは、バイナリとテキストの両方を扱えるCOMオブジェクトです。
文字列をUTF-8へ変換する場合は、まずテキストモードで書き込みます。
stream.Type = adTypeText
stream.Charset = "utf-8"
stream.WriteText value
その後、バイナリモードへ切り替えて読み出します。
stream.Position = 0
stream.Type = adTypeBinary
stream.Position = 3
Utf8Bytes = stream.Read(adReadAll)
Position = 3としているのは、ADODB.Streamが付けるUTF-8 BOMを読み飛ばすためです。
BOMが本文の先頭に残ると、GAS側でtokenが一致しないなど、見えない不具合になります。
デコード側では、COMから返ってきたresponseBodyをVariantとして受け、バイナリとして書き込んでからテキストモードで読みます。
stream.Type = adTypeBinary
stream.Write bytes
stream.Position = 0
stream.Type = adTypeText
stream.Charset = "utf-8"
Utf8Decode = stream.ReadText(adReadAll)
注意点
.Readや.ReadTextには省略せず-1を渡すTypeを切り替える前にPosition = 0へ戻す- エンコード時はBOMを取り除く
- デコード側の引数は
Byte()ではなくVariantにする Microsoft ActiveX Data Objectsの参照設定なしでも使えるよう、遅延バインディングにする
関連記事
- Excel VBAからGAS Web APIへTSVでPOSTする実装定石
- VBAでCOMに配列を渡すときはVariantで受ける
- PowerShell / bat運用で文字コードと改行コードを固定する
まとめ
VBAからWeb APIへ日本語を送るなら、UTF-8変換を小さな汎用プロシージャに切り出しておくと安定します。
Utf8BytesとUtf8Decodeを共通部品にしておくことで、GAS連携や外部API連携のたびに文字化け対策を考え直さずに済みます。
