VBAでWeb API(REST API)を使うときの作法
巷でVBAが古い、使えない、ゴミ、カメムシと言われる理由をここで改めて書くことはしませんが、少なくともVBAで凝ったことをしようとすれば最終的には他の言語の知識が必須になります。
というかそもそも名前からしてfor Applicationsなので…というところもあり、
- VBAから金の匂いがする
- 宗教上の理由でGoogle Appsが使えない
- 足りない機能を補うためWScriptからPowerShellを立ち上げて.NET Frameworkの関数を呼ぶような実装に何らかの興奮を覚える
といった特殊な環境に置かれた諸兄以外はあまりVBAを突き詰める必要はないと思います。
今回お話しするWebAPIもそんなVBAの苦手分野の1つで、諸々の理由と相まってネット上にはヤバいコードがごろごろ転がっています。
流石にあれを業務で使うのもアレなので、本稿ではVBAでもそこそこまともにWebAPIを叩く方法を考えていきます。
JSONデータはVBA-JSONに委ねる
VBAからJSONを扱うのであれば現状これが一番楽だと思われます。
パースがとにかく楽。
32ビット環境であればScriptControlという手もあるのですが、JSONオブジェクトが使いにくいのでどの道あまりオススメはしません。
配布する場合はライセンス表記と参照設定について注意してください。
パラメータは連想配列にまとめる
Const attack = 155 Const defence = 120 Const speed = 105
のようにパラメータを1つずつ定数や変数に入れるとコードが冗長になります。
VBAでは文字列から変数や定数の値を取得することができないため、
このやり方ではAPIのパラメータ名と値が紐付かないのです。
というわけで連想配列の出番です。
Dim param As Object Set param = CreateObject("Scripting.Dictionary") With param .Add "attack", 155 .Add "defence", 120 .Add "speed", 105 End With
これであればパラメータ名と値が直接紐付きますし、可読性も良くなります。
APIをキックする部分は関数化する
さて、ここまできちんと準備をすれば関数自体もシンプルに書けます。
Public Function KickAPI( _ ByVal request As String, _ ByVal URL As String, _ ByVal paramType As Long, _ Optional ByVal param As Object) As Object With CreateObject("MSXML2.XMLHTTP") .Open request, URL, False Select Case paramType Case 1 .SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" .send (ConvertToQueryString(param)) Case 2 .SetRequestHeader "Content-Type", "application/json; charset=UTF-8" .send (ConvertToJson(param)) End Select If .ResponseText <> "" Then Set KickAPI = ParseJson(.ResponseText) End If End With End Function Private Function ConvertToQueryString(ByVal dic As Object) As String If dic Is Nothing Then Exit Function Dim key As Variant For Each key In dic.keys ConvertToQueryString = ConvertToQueryString & "&" & key & "=" & dic.Item(key) Next End Function 'ConvertToJson及びParseJsonは上記VBA-JSONに含まれる関数です。 '連想配列をクエリ文字列に変換する関数の名前もこれに寄せてみました。
実際にはここにアクセストークンの有無なんかも入ってきてもう少しごちゃごちゃするのですが、基本はこんなもん。
あとはこれを使うAPIにあわせてカスタマイズしていけば、メンテナンス性の高いコードが書けるはずです。