がらくた日記

趣味のブログ

VBA-JSONでネストされた深いところにあるJSONデータを取得する

VBAJSONデータのパースは素晴らしいモジュールがあるのでそれを利用させてもらってますが、深い階層のデータ取得方法について書き留めておく。

まあ、開発者のページを読むと書いてあることではありますが。。。

VBA-JSONはここから https://github.com/VBA-tools/VBA-JSON/releases

解析したいJSON

{
    "Dates": {
        "OutboundDates": [
            {
                "PartialDate": "2019-09-03",
                "QuoteIds": [
                    1
                ],
                "Price": 83.0,
                "QuoteDateTime": "2019-08-22T10:43:00"
            },
            {
                "PartialDate": "2019-09-10",
                "QuoteIds": [
                    2
                ],
                "Price": 94.0,
                "QuoteDateTime": "2019-08-24T12:14:00"
            }

VBAでは":"記号の右側にあるデータをitemsプロパティからVariant型で取得でき、複数あるときはFor Each in Next文などでループして取得できるのだが、 いちばん注意したいのは配列の開始を表す"["の記号。

パースされた情報は"["から"]"までを一つの配列として処理しているから、配列"[...]"単位でループをネストさせながら深い階層に入っていく。

上のJSONをパースしたものをresult1に格納したとして、"Dates"直下のデータを取得したいときは

result1("Dates")

もう一つ下の"Dates"の中の"OutboundDates"の階層のデータを取得したいときは、

result1("Dates")("OutboundDates")

のように()で引数を増やして希望の階層まで下がっていき、そこにあるデータをFor Each in Next文でループして取得する。 "PartialDate"、"QuoteIds"、"Price"、"QuoteDateTime"の各データを取得したいときは、

VBA

Sub Deepsea()
'参照設定 Microsoft Scripting Runtime
'参照設定 Microsoft XML. v6.0

Dim objXMLHttp As New MSXML2.XMLHTTP60
Dim result1 As New Scripting.Dictionary
Dim result2 As New Scripting.Dictionary
Dim i As Variant

objXMLHttp.Open  "GET", "http://... ", False
objXMLHttp.send

Set result1 = JsonConverter.ParseJson(objXMLHttp.responseText)

    For Each result2 In result1("Dates")("OutboundDates")
        For Each i In result2.Items
            Debug.Print i
        Next
    Next

ここで、残念ながら"QuoteIds"のデータだけは取得できない。"QuoteIds"はさらにその中が配列"[...]"になっているから。

データは"["記号から次の"["までの間しか取得できないので、"QuoteIds"の中データを取得したいときは

result1("Dates")("OutboundDates")("QuoteIds")

のようにさらに()で引数を増やしてこの配列の中に入りデータを取得する。