はじめに
業務でVBAのプログラムを作っていた時に、内閣府の祝日情報を扱いたいと思ったのですが、VBAではお手軽にHTTP/HTTPS通信出来る組み込みの関数が用意されていませんでした。
(※内閣府の祝日情報はCSV形式で提供されています。)
そこで様々なサイトを参考にしながら、HTTP/HTTPS通信でWebページを取得できるモジュール(クラス)を作成してみました。
作成したクラス
- VBAでHTTP通信するプログラムを作るにあたり、こちらの記事を参考にしてベースのプログラムを作りました。
- また、HTTPS通信に対応させるにあたって、こちらの記事を参考にしました。
- 幾つかのサイトで紹介されていたサンプルコードには
CreateObject("MSXML2.XMLHTTP")
が使われていましたが、この書き方だとTLS1.2を利用しているページでエラーとなってしまいます。 - HTMLではなく単なるテキストファイルをDLする場合などは、レスポンスヘッダに適切な文字コードが指定されていないことがありますが、その場合は
StrConv(httpObj.responseBody, {適切な文字コード})
でコンテンツを取得してください。 - StrConv関数
- データをバイト配列として取得
- バイト配列を文字列に変換
- レスポンスヘッダに文字コードが無い場合の挙動
HttpClient.bas
Option Explicit
'--------------------------------------------------------------------------------
' HTTP通信用クラス。
'--------------------------------------------------------------------------------
' HTTP通信用オブジェクト
Private httpObj As Object
'--------------------------------------------------------------------------------
' コンストラクタ
'--------------------------------------------------------------------------------
Public Sub Class_Initialize()
'Set httpObj = CreateObject("MSXML2.XMLHTTP") ' TLS1.2に非対応
Set httpObj = CreateObject("MSXML2.ServerXMLHTTP")
End Sub
'--------------------------------------------------------------------------------
' デストラクタ
'--------------------------------------------------------------------------------
Public Sub Class_Terminate()
Set httpObj = Nothing
End Sub
'--------------------------------------------------------------------------------
' 引数のURLをGETメソッドで取得する。
'
' url:URL文字列。
' return:取得したページ。
'--------------------------------------------------------------------------------
Public Function GetPage(url As String) As String
httpObj.Open "GET", url
httpObj.send
' readyState=4で読み込みが完了
Do While httpObj.readyState < 4
DoEvents
Loop
Dim statusCode As Integer
statusCode = httpObj.Status
' HTTPのステータスコードが200(OK)以外であれば、ステータスコードなどを返す。
If (statusCode = 200) Then
' GetPage = httpObj.responseText ' レスポンスの文字コードがShift_JIS(MS932)の時はこちらを使う。
GetPage = StrConv(httpObj.responseBody, vbUnicode)
Else
GetPage = "HTTP StatusCode:" & statusCode & ", HTTP StatusText:" & httpObj.statusText
End If
End Function
テストコード
TestHttpClient.bas
Option Explicit
Public Sub TestHttpClient()
Dim httpObj As HttpClient
Set httpObj = New HttpClient
Dim response As String
response = httpObj.GetPage("https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv")
Debug.Print response
End Sub
まとめ
- 当初はHTTPS通信に対応させる方法が分からずに四苦八苦しましたが、結果的に簡単な方法でクリアできて良かったです。
- 中には「レジストリを書き換える」というような方法を紹介しているページもありましたが、そこで諦めずに色々調べてみて良かったです...
その他
- VBAの組み込み関数を補うために作成した自作の関数などは、以下のページにもアップしています。
- 【ExcelVBA】文字列操作用のユーティリティ関数を自作してみた
- 【ExcelVBA】日時操作用のユーティリティ関数を自作してみた
- 【ExcelVBA】ハッシュ値を取得する関数を自作してみた