経理屋とVBAの日記

経理業務で役に立つかもしれないExcel/Access VBAのネタを書きます

VBAでWeb API(REST API)を使うときの作法

 巷でVBAが古い、使えない、ゴミ、カメムシと言われる理由をここで改めて書くことはしませんが、少なくともVBAで凝ったことをしようとすれば最終的には他の言語の知識が必須になります。


というかそもそも名前からしてfor Applicationsなので…というところもあり、

  • VBAから金の匂いがする
  • 宗教上の理由でGoogle Appsが使えない
  • 足りない機能を補うためWScriptからPowerShellを立ち上げて.NET Frameworkの関数を呼ぶような実装に何らかの興奮を覚える

といった特殊な環境に置かれた諸兄以外はあまりVBAを突き詰める必要はないと思います。


 今回お話しするWebAPIもそんなVBAの苦手分野の1つで、諸々の理由と相まってネット上にはヤバいコードがごろごろ転がっています。
 流石にあれを業務で使うのもアレなので、本稿ではVBAでもそこそこまともにWebAPIを叩く方法を考えていきます。

定義

使用するAPIですが、今回は

  • REST API
  • パラメータの形式はクエリ文字列かJSON
  • レスポンスはJSON(か空)

とさせてください。XMLについては記事の最後で少しだけ触れます。

ポイント

前置きが長くなりましたが、ポイントは3つです。

  • APIをキックする部分は関数化する
  • パラメータは連想配列にまとめる
  • JSONデータはVBA-JSONに委ねる

あえて逆順で説明していきます。

JSONデータはVBA-JSONに委ねる

github.com

  • JSONをパースして連想配列にする
  • 連想配列やコレクションから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にあわせてカスタマイズしていけば、メンテナンス性の高いコードが書けるはずです。

    終わりに

     いかがでしょうか。とにかくVBA-JSONが非常に便利なので、これを中心に組むことが省エネへの一番の近道になると思います。
     ちなみに同じ作者のVBA-XMLというのもあるので、気になる方は是非触ってみて使用感を教えてください。