Извлечь JSON в Excel VBA - PullRequest
0 голосов
/ 09 мая 2018

Я хочу проанализировать котировки акций из API Робин Гуда через Excel VBA.

Скажи, что я хочу Amazon, который https://api.robinhood.com/quotes/?symbols=AMZN.

Который производит:

{  
   "results":[  
      {  
         "ask_price":"1592.3900",
         "ask_size":100,
         "bid_price":"1591.0000",
         "bid_size":500,
         "last_trade_price":"1592.3900",
         "last_extended_hours_trade_price":"1592.0000",
         "previous_close":"1600.1400",
         "adjusted_previous_close":"1600.1400",
         "previous_close_date":"2018-05-07",
         "symbol":"AMZN",
         "trading_halted":false,
         "has_traded":true,
         "last_trade_price_source":"consolidated",
         "updated_at":"2018-05-08T23:58:44Z",
         "instrument":"https://api.robinhood.com/instruments/c0bb3aec-bd1e-471e-a4f0-ca011cbec711/"
      }
   ]
}

Используя такой пример, как этот ответ , я установил VBA-JSON и включил Microsoft Scripting Runtime.

Мой код:

Public Sub STOCKQUOTE()

 Dim http As Object
 Set http = CreateObject("MSXML2.XMLHTTP")

 Const sURL As String = "https://api.robinhood.com/quotes/?symbols=AMZN"
 http.Open "GET", sURL, False
 http.send

 Dim jsonResponse As Dictionary
 Set jsonResponse = JsonConverter.ParseJson(http.responseText)

 Dim results As String
 Set results = jsonResponse("results")

 MsgBox results
End Sub

Но это не работает, вместо этого я получаю Compiler Error: Object Required для строки Set results = jsonResponse("results").

Если я добавлю Debug.Print http.responseText Я вижу правильный JSON, но есть идеи, что я делаю неправильно?

VBA-JSON установлен правильно, потому что, если я использую их пример , он отлично работает:

Dim Json As Object
Set Json = JsonConverter.ParseJson("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")

Но если я попытаюсь изменить Dictionary на Object, я получу Run-time error '450': Wrong number of arguments or invalid property assignment.

1 Ответ

0 голосов
/ 09 мая 2018

У вашего json есть объект с именем results. Может быть, но не несколько result объектов. У вас есть только один, поэтому я думаю, что это приводит к путанице. Каждый result получит свою собственную запись в вашем jsonResponse словаре. ПУНКТ в этом словаре сам по себе будет словарем.

Лучший способ справиться с итерацией по словарю в словаре - это объявить новый словарь, я вызываю att для «Атрибутов», а затем заполнять этот словарь каждой итерацией через словарь jsonResponse. Это будет повторяться только один раз, хотя у вас есть только один result:

Public Sub STOCKQUOTE()

    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP")

    Const sURL As String = "https://api.robinhood.com/quotes/?symbols=AMZN"
    http.Open "GET", sURL, False
    http.send

    Dim jsonResponse As Dictionary
    Set jsonResponse = JsonConverter.ParseJson(http.responseText)

    Dim att As Dictionary

    For Each att In jsonResponse("results")
     Debug.Print att("last_trade_price")
    Next att
End Sub

В качестве альтернативы, поскольку у вас есть только один результат, вы можете просто сослаться на этот результат по его индексу в словаре jsonResponse, а затем по его атрибуту. Это делает код меньше, но если вы когда-либо получите более одного результата от вашего запроса REST, он будет потерян навсегда. Но не важно, так как вы не ожидаете, что это произойдет:

Public Sub STOCKQUOTE()

    Dim http As Object
    Set http = CreateObject("MSXML2.XMLHTTP")

    Const sURL As String = "https://api.robinhood.com/quotes/?symbols=AMZN"
    http.Open "GET", sURL, False
    http.send

    Dim jsonResponse As Dictionary
    Set jsonResponse = JsonConverter.ParseJson(http.responseText)

    MsgBox (jsonResponse("results")(1)("last_trade_price"))

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...