VBAでparseしたJSONデータの要素を取得する方法

Web APIを使っていると、リクエストに対するレスポンスデータがJSONデータってことが一般的だ。JSONデータはキーと値のペア、すなわち連想配列になっているわけだが、これをparseすることで、キーを指定すれば値を取り出すことが可能となる。別にparseしなくても欲しい値を取り出することできるが、難儀して自分で取り出す処理を作ることになる。有難いことに、どなたかがparse用のライブラリを作成してGitHubに公開しているので、使わせてもらう。

VBA-JSON(JSONデータparse用ライブラリ)の導入

まずはVBAでJSONデータをparseするためのライブラリをGitHubから落とす。以下サイトに移動する。
https://github.com/VBA-tools/VBA-JSON
図1の赤枠の「Code」→「Download ZIP」とクリックする。

図1:GitHubからJSON parse用のライブラリをダウンロード

ダウンロードされたファイルを解凍(展開)して、その中に含まれているJsonConverter.basを自身のVBAプロジェクトにインポートする。 また、先ほどのWebページの下部に記載されているように、参照設定に “Microsoft Scripting Runtime” を追加する。(図2の赤線参照) これにてparseする準備は完了。

図2:参照設定について

JSONデータ構造の確認

次に本題のJSONデータからどうやってデータを取り出すか見ていく。サンプルデータとして次のデータを用意した。
{";term1";:";abc";,";term2";:{";term3";:123,";term4";:";def";,";term5";:[456,{";term6";:";789";,";term7";:";012";}]}}
ただし、このままだと見栄えが悪く、データ構造が分かりにくい。この程度のデータならまだ読めるかもしれないが、実際にWeb APIが返してくるデータはもっとデータ量が多くて複雑なことがほとんどだ。

ネット上にはJSONデータを見栄えよく整形して表示するサイトがいくつかあるので、それを使ってデータ構造を確認するのが良い。データ構造を簡単につかむことができれば、プログラムを書くのも容易となる。
例えば、以下のサイトで整形したものが図3。
https://tools.m-bsys.com/development_tooles/json-beautifier.php

図3:オンラインサイトでJSONデータをフォーマットできる

JSONデータを取得するサンプルコード

各値を取得するサンプルコードを以下に示そう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Sub CheckJsonConverter()
    Dim docObj, wkStr

    wkStr = "{""term1"":""abc"",""term2"":{""term3"":123,""term4"":""def"",""term5"":[456,{""term6"":""789"",""term7"":""012""}]}}"
    Set docObj = JsonConverter.ParseJson(wkStr)

    ' 直接項目名を指定してのアクセス
    Debug.Print docObj("term1")                      ' abc
    Debug.Print docObj("term2")("term3")             ' 123
    Debug.Print docObj("term2")("term4")             ' def
    Debug.Print docObj("term2")("term5").Count       ' 2
    Debug.Print docObj("term2")("term5")(1)          ' 456
    Debug.Print docObj("term2")("term5")(2)("term6") ' 789
    Debug.Print docObj("term2")("term5")(2)("term7") ' 012

    ' 項目数の確認方法
    Debug.Print docObj.Count                         ' 2
    Debug.Print docObj("term2").Count                ' 3

    ' 項目名の存在チェック方法
    Debug.Print docObj.Exists("term2")               ' True
    Debug.Print docObj.Exists("term3")               ' False

    ' インデックスでのアクセス
    Debug.Print docObj("term2")(0)                   ' 何も出力されない
    Debug.Print docObj("term2").items()(0)           ' 123
    Debug.Print docObj("term2").items()(1)           ' def

    ' いったんバリアント型に代入すると、配列として扱える
    Dim items
    items = docObj("term2").items
    Debug.Print items(0)                             ' 123
    Debug.Print items(1)                             ' def
    Debug.Print items(2)(1)                          ' 456
    Debug.Print items(2)(2).items()(0)               ' 789

End Sub

5行目でライブラリを呼び出してJSONデータをparseしている。 7行目以降で、データの取得コードと、右側のコメントに出力結果を載せている。基本的には、キーを指定すれば値を取り出せることが分かると思う。 また、連想配列ではなく単純な配列から値を取り出す場合は、インデックス指定でのアクセスとなる。

連想配列に対して、キー指定でなくインデックス指定でも値を取り出すことは一応可能だ(26,27行目)。ただし、少し注意が必要。 25行目のようなコードは、term2の値が単純な配列の場合の書き方だ。しかしterm2の値は連想配列なので取得できない。インデックスを指定する場合は、26行目のようなitemsメソッドを使った方法になる。

このitemsメソッドの使い方も要注意で、items()(0)ではなくitems(0)と書いた場合は、図4のようなエラーとなる。

図4:itemメソッドの不正使用時に出るエラー

29行目以降のように、いったんバリアント型に代入すると配列として扱えるので、インデックス指定も割と容易になる。しかし、35行目のように子孫の値の状況によってはitemsメソッドを使うことになるので、インデックス指定は避けるのが無難だと思う。

参考動画

表示が小さいので、全画面表示にするなどして、できるだけ拡大した方が見やすいと思う。

How to parse JSON with VBA-JSON

関連ページ