2015-04-10 2 views
2

Итак, я уже задал вопрос, который был успешно ответил (здесь: Parsing JSON (US BLS) in VBA from MS Access)Синтаксический JSON (US BLS) в VBA из MS Access, обновление

Новый ответ я получаю, что отличается от оригинала вопрос заключается в том, что Я добавил запрос на захват расчетов. Я попробовал добавить в качестве словаря для коллекции и скриптинга, например сноски, но я вижу, что формат не совсем то же самое, поэтому я думаю, что это приводит к ошибке, когда я пытаюсь собрать изменения 1,3,6 и 12 месяцев. Я хотел бы иметь некоторую помощь выяснить, как захватить эти изменения в следующей реакции:

{ 
    "status":"REQUEST_SUCCEEDED", 
    "responseTime":64, 
    "message":["BLS does not produce net change calculations for Series WPU381103"], 
    "Results": 
    { 
     "series": 
     [ 
      { 
       "seriesID":"WPU381103", 
       "data": 
       [ 
        { 
         "year":"2014", 
         "period":"M12", 
         "periodName":"December", 
         "value":"98.9", 
         "footnotes": 
         [ 
          { 
           "code":"P", 
           "text":"Preliminary. All indexes are subject to revision four months after original publication." 
          } 
         ], 
         "calculations": 
         { 
          "net_changes":{}, 
          "pct_changes": 
          { 
           "1":"0.0", 
           "3":"0.1", 
           "6":"0.0", 
           "12":"-0.7" 
          } 
         } 
        }, 
        { 
         "year":"2014", 
         "period":"M11", 
         "periodName":"November", 
         "value":"98.9", 
         "footnotes": 
         [ 
          { 
           "code":"P", 
           "text":"Preliminary. All indexes are subject to revision four months after original publication." 
          } 
         ], 
         "calculations": 
         { 
          "net_changes":{}, 
          "pct_changes": 
          { 
           "1":"0.1", 
           "3":"-0.4", 
           "6":"0.0", 
           "12":"-0.7" 
          } 
         } 
        },... 

Вы заметите, что есть часть теперь, говорит, расчеты, и отделяю значение от чистых изменений, а также изменения процента , Я пытаюсь получить процентные изменения в элементах данных «1», «3», «6» и «12».

Вот текущий код, который я не нашел вычислений, но захватывает все остальные данные:

response = http.responseText 
jsonSource = response 

I = 0 

Dim jsonData As Scripting.Dictionary 
Set jsonData = JSON.parse(jsonSource) 
Dim responseTime As String 
responseTime = jsonData("responseTime") 

Dim results As Scripting.Dictionary 
    On Error Resume Next 
Set results = jsonData("Results") 

Dim series As Collection 
On Error Resume Next 
Set series = results("series") 

Dim seriesItem As Scripting.Dictionary 
For Each seriesItem In series 
    Dim seriesId As String 
    seriesId = seriesItem("seriesID") 


    Dim Data As Collection 
    Set Data = seriesItem("data") 

    Dim dataItem As Scripting.Dictionary 
    For Each dataItem In Data 
     Dim Year As String 
     Year = dataItem("year") 
I = 1 + I 
     Dim Period As String 
     Period = dataItem("period") 

     Dim periodName As String 
     periodName = dataItem("periodName") 

     Dim Value As String 
     Value = dataItem("value") 

     Dim footnotes As Collection 
     Set footnotes = dataItem("footnotes") 

     Dim footnotesItem As Scripting.Dictionary 
     For Each footnotesItem In footnotes 
      Dim Code As String 
      Code = footnotesItem("code") 

      Dim text As String 
      text = footnotesItem("text") 

     Next footnotesItem 
    Next dataItem 
Next seriesItem 

ответ

3

Довольно прямо вперед. Помните, что модуль JSON реализует массивы JavaScript как коллекции и объекты как экземпляры Scripting.Dictionary.

В вашем контексте [..].calculations, [..].calculations.net_changes и [..].calculations.pct_changes - все объекты, поэтому все они превращены в объекты Словаря.

Так что в вашем коде, после For Each footnotesItem In footnotes: [..]: Next footnotesItem блока (следовательно, выше & до Next dataItem линии), можно добавить следующие строки:

Dim calculations As Scripting.Dictionary 
Dim sIndent As String 
Dim calcNetChanges As Scripting.Dictionary 
Dim calcPctChanges As Scripting.Dictionary 
Dim varItem As Variant 
     Set calculations = dataItem("calculations") 
     sIndent = String(4, " ") 
     Set calcNetChanges = calculations("net_changes") 
     Debug.Print Year & ", " & Period & " (" & periodName & ") - Net Changes:" 
     If calcNetChanges.Count > 0 Then 
      For Each varItem In calcNetChanges.keys 
       Debug.Print sIndent & CStr(varItem) & ": " & calcNetChanges.Item(varItem) 
      Next varItem 
     Else 
      Debug.Print sIndent & "(none)" 
     End If 
     Set calcPctChanges = calculations("pct_changes") 
     Debug.Print Year & ", " & Period & " (" & periodName & ") - Pct Changes:" 
     If calcPctChanges.Count > 0 Then 
      For Each varItem In calcPctChanges.keys 
       Debug.Print sIndent & CStr(varItem) & ": " & calcPctChanges.Item(varItem) 
      Next varItem 
     Else 
      Debug.Print sIndent & "(none)" 
     End If 

, которые при условии, что данные JSON, должен выводить что-то вроде это:

2014, M12 (December) - Net Changes: 
    (none) 
2014, M12 (December) - Pct Changes: 
    1: 0.0 
    3: 0.1 
    6: 0.0 
    12: -0.7 
2014, M11 (November) - Net Changes: 
    (none) 
2014, M11 (November) - Pct Changes: 
    1: 0.1 
    3: -0.4 
    6: 0.0 
    12: -0.7 

Если вы хотите получить доступ пункты calculations.net_changes и calculations.pct_changes непосредственно их ключей (заранее известны), вы бы заменить два For Each varItem блоков, соответственно:

If calcNetChanges.Exists("1") Then Debug.Print "1: " & calcNetChanges.Item("1") 
If calcNetChanges.Exists("3") Then Debug.Print "3: " & calcNetChanges.Item("3") 
If calcNetChanges.Exists("6") Then Debug.Print "6: " & calcNetChanges.Item("6") 
If calcNetChanges.Exists("12") Then Debug.Print "12: " & calcNetChanges.Item("12") 

[..] 

If calcPctChanges.Exists("1") Then Debug.Print "1: " & calcPctChanges.Item("1") 
If calcPctChanges.Exists("3") Then Debug.Print "3: " & calcPctChanges.Item("3") 
If calcPctChanges.Exists("6") Then Debug.Print "6: " & calcPctChanges.Item("6") 
If calcPctChanges.Exists("12") Then Debug.Print "12: " & calcPctChanges.Item("12") 

Наконец, следует отметить, что в JSon данных вы даете в качестве примера, процентов (т.е. Значения элементов для [..].calculations.net_changes & [..].calculations.pct_changes) предоставляются в качестве строк, поэтому вы, вероятно, хотите, чтобы преобразовать те в Double (или одинарных данные) с помощью Val() для выполнения математика или другие числовых операций над ними, например:

Dim pctChange_1 As Double, pctChange_3 As Double 
Dim pctChange_6 As Double, pctChange_12 As Double 
    pctChange_1 = 0# 
    pctChange_3 = 0# 
    pctChange_6 = 0# 
    pctChange_12 = 0# 
    If calcPctChanges.Exists("1") Then pctChange_1 = CDbl(Val(calcPctChanges.Item("1"))) 
    If calcPctChanges.Exists("3") Then pctChange_3 = CDbl(Val(calcPctChanges.Item("3"))) 
    If calcPctChanges.Exists("6") Then pctChange_6 = CDbl(Val(calcPctChanges.Item("6"))) 
    If calcPctChanges.Exists("12") Then pctChange_12 = CDbl(Val(calcPctChanges.Item("12"))) 
+0

Спасибо @johnwait, это было очень хорошо объяснено и подробно, дал мне много вариантов, и улучшилось мое понимание.Я смог использовать этот код и даже внести некоторые небольшие изменения в соответствие с представлением данных на основе знаний, которые вы указали. – Dm3k1

1

Объявляет расчеты как Scripting.Dictionary и его РСТ-изменений как Scripting.Dictionary, а также. Добавьте следующий фрагмент кода после кода для сносок. НТН

Dim calculations As Scripting.Dictionary 
Set calculations = dataItem("calculations") 

Dim pct_changes As Scripting.Dictionary 
Set pct_changes = calculations("pct_changes") 

Dim pct_change As Variant 
For Each pct_change In pct_changes 
    Debug.Print pct_change & ":" & pct_changes(pct_change) 
Next pct_change 

Debug.Print pct_change & ":" & pct_changes(pct_change) производит следующий результат для первых расчетов, установленных:

1:0.0 
3:0.1 
6:0.0 
12:-0.7 
+0

Эй, Ди, еще раз спасибо, ты помог и в предыдущем вопросе, я ценю твою мудрость! – Dm3k1