Get data from json array with in array? - arrays
I have a json like with this format
[{"ts_id": "96643010","rows": "64","columns":"Timestamp,Value", "data": [["2021-09-01T11:00:00.000+07:00",206.95],["2021-09-01T12:00:00.000+07:00",206.96],["2021-09-01T13:00:00.000+07:00",206.97],["2021-09-01T14:00:00.000+07:00",206.95],["2021-09-01T15:00:00.000+07:00",206.92],["2021-09-01T16:00:00.000+07:00",206.89],["2021-09-01T17:00:00.000+07:00",206.86],["2021-09-01T18:00:00.000+07:00",206.83],["2021-09-01T19:00:00.000+07:00",206.80],["2021-09-01T20:00:00.000+07:00",206.77],["2021-09-01T21:00:00.000+07:00",206.74],["2021-09-01T22:00:00.000+07:00",206.71],["2021-09-01T23:00:00.000+07:00",206.68],["2021-09-02T00:00:00.000+07:00",206.65],["2021-09-02T01:00:00.000+07:00",206.63],["2021-09-02T02:00:00.000+07:00",206.65],["2021-09-02T03:00:00.000+07:00",206.67],["2021-09-02T04:00:00.000+07:00",206.69],["2021-09-02T05:00:00.000+07:00",206.71],["2021-09-02T06:00:00.000+07:00",206.73],["2021-09-02T07:00:00.000+07:00",206.75],["2021-09-02T08:00:00.000+07:00",206.76],["2021-09-02T09:00:00.000+07:00",206.77],["2021-09-02T10:00:00.000+07:00",206.78],["2021-09-02T11:00:00.000+07:00",206.79],["2021-09-02T12:00:00.000+07:00",206.80],["2021-09-02T13:00:00.000+07:00",206.81],["2021-09-02T14:00:00.000+07:00",206.82],["2021-09-02T15:00:00.000+07:00",206.83],["2021-09-02T16:00:00.000+07:00",206.83],["2021-09-02T17:00:00.000+07:00",206.83],["2021-09-02T18:00:00.000+07:00",206.83],["2021-09-02T19:00:00.000+07:00",206.83],["2021-09-02T20:00:00.000+07:00",206.83],["2021-09-02T21:00:00.000+07:00",206.84],["2021-09-02T22:00:00.000+07:00",206.85],["2021-09-02T23:00:00.000+07:00",206.86],["2021-09-03T00:00:00.000+07:00",206.87],["2021-09-03T01:00:00.000+07:00",206.89],["2021-09-03T02:00:00.000+07:00",206.91],["2021-09-03T03:00:00.000+07:00",206.93],["2021-09-03T04:00:00.000+07:00",206.95],["2021-09-03T05:00:00.000+07:00",206.96],["2021-09-03T06:00:00.000+07:00",206.97],["2021-09-03T07:00:00.000+07:00",206.98],["2021-09-03T08:00:00.000+07:00",207.00],["2021-09-03T09:00:00.000+07:00",207.02],["2021-09-03T10:00:00.000+07:00",207.04],["2021-09-03T11:00:00.000+07:00",207.06],["2021-09-03T12:00:00.000+07:00",207.08],["2021-09-03T13:00:00.000+07:00",207.11],["2021-09-03T14:00:00.000+07:00",207.14],["2021-09-03T15:00:00.000+07:00",207.17],["2021-09-03T16:00:00.000+07:00",207.18],["2021-09-03T17:00:00.000+07:00",207.19],["2021-09-03T18:00:00.000+07:00",207.20],["2021-09-03T19:00:00.000+07:00",207.20],["2021-09-03T20:00:00.000+07:00",207.20],["2021-09-03T21:00:00.000+07:00",207.20],["2021-09-03T22:00:00.000+07:00",207.19],["2021-09-03T23:00:00.000+07:00",207.18],["2021-09-04T00:00:00.000+07:00",207.17],["2021-09-04T01:00:00.000+07:00",207.18],["2021-09-04T07:00:00.000+07:00",207.30]]}]
Blockquote
I have tried to get this data with VBA but unsuccess, somebody can help me with VBA code to get data from "data".
This the code i have used:
Public Sub exceljson()
Dim http As Object, JSON As Object, i As Integer
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "https://cdh.vnmha.gov.vn/KiWIS/KiWIS?service=kisters&type=queryServices&request=getTimeseriesValues&datasource=0&format=dajson&ts_id=96643010&period=P3D", False
http.Send
Set JSON = ParseJson(http.responseText)
i = 2
For Each Item In JSON
Sheets(1).Cells(i, 1).Value = Item("data")
i = i + 1
Next
MsgBox ("complete")
End Sub
Related
Accessing keys and values in nested object with VBA
I use the translation API from Deepl in VBA. My request is working pretty fine and returns some translated html-text. However, I am not able to get the "text"-value in the returned object: So my request looks as follows: Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP") url = api & "?" & authKey & "&" & targetLng & "&" & tagHandling & "&" & sourceLng Debug.Print url objHTTP.Open "POST", url, False objHTTP.setRequestHeader "Host", "api-free.deepl.com" objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" objHTTP.setRequestHeader "Accept", "*/*" objHTTP.send "text=" & text textResponse = objHTTP.responseText 'textResponse is defined as String Debug.Print textResponse I get the following output: { "translations": [ {"detected_source_language":"DE", "text":"<h2>SizeI</h2>love \"Paperwhite\".<br><br><img src=\"https://ws-eu.amazon-adsystem.com/widgets/q?_encoding=UTF8" } ] } I further tried: 'get the script control: Set ScriptEngine = CreateObject("ScriptControl") ScriptEngine.Language = "JScript" 'Get the string and parse it: Set jsonObject = ScriptEngine.Eval("(" & textResponse & ")") jsonObject returns [object Object] and I have no idea how to process this. How can I access this object and return just the text-value?
Using VBA-JSON from here: https://github.com/VBA-tools/VBA-JSON Function Test20220318() Dim json As Object, txt, trans As Collection, t As Object, k txt = [E1].Value 'using json stored in a cell for testing Set json = JsonConverter.ParseJson(txt) 'a Dictionary object Set trans = json("translations") 'access dictionary by key to get collection/array For Each t In trans 'loop over items in collection/array For Each k In t 'loop over keys in t Debug.Print k, "=", t(k) 'print key and associated value Next Next t End Function
The response is a JSON String. You have to convert the JSON string to an object Set jsonObject = DecodeJsonString(objHTTP.responseText)
Access response in Json
I am using the JSON VBA library to parse a large JSON response but I can not access the elements of the response as expected. For example the response has the structure: {employees: [{employeeId: {id: 1234}, personNumber: "ABC123", shortName: "Bob",...},...],...} I have tried : Dim JsonPayload As Object Set JsonPayload = JsonConverter.ParseJson(req.ResponseText) MsgBox JsonPayload("dict_pDictionary") MsgBox JsonPayload("employees")(1)("employeeId") And also : Set emp = JsonPayload("employees") For Each e In emp Debug.Print "employee", e.shortName Debug.Print "shortName", e Debug.Print "shortName", e.dict_pDictionary Next e The error is Object Does not support this property or method. I would like to know how to loop over the response. Some are variant/object/dictionary and other parts seem to be variant/object/collection
VBA JSON converts objects ({}) to Dictionaries, and Arrays ([]) to Collections. In your code e is a Dictionary object, not an object with named properties, so: Dim jso As Object, emps, e Set jso = JsonConverter.ParseJson( _ "{""employees"":[{""employeeId"": {""id"": 1234}, ""personNumber"": ""ABC123"", ""shortName"": ""Bob""}]}") Set emps = jso("employees") For Each e In emps Debug.Print e("employeeId")("id") '>> 1234 Debug.Print e("shortName") '>> Bob Next e
How to get, JSON values to Work in VBA-JSON?
I am trying to access nested JSON values that come back from the API that I am working with at the moment. There seem to be no field names to use in this JSON, making it very difficult to follow most examples online. API URL - CLICK HERE I am using VBA-JSON through this process, and I've got it to successfully display "responseText" in MsgBox. I am looking for a way to make this code work. Public Sub exceljson() Dim http As Object, JSON As Object, i As Integer Set http = CreateObject("MSXML2.XMLHTTP") http.Open "GET", "https://api.bitfinex.com/v2/candles/trade:5m:tEOSUSD/hist?start=1535760000000&end=1538265600000&sort=1", False http.Send Set JSON = ParseJson(http.responseText) i = 2 For Each Item In JSON Sheets(1).Cells(i, 1).Value = Item("one") ' Items reference as an example Sheets(1).Cells(i, 2).Value = Item("two") Sheets(1).Cells(i, 3).Value = Item("three") Sheets(1).Cells(i, 4).Value = Item("four") Sheets(1).Cells(i, 5).Value = Item("five") i = i + 1 Next MsgBox ("complete") End Sub
In my answer to Using VBA and VBA-JSON to access JSON data from Wordpress API , I wrote a function, PrintJSONAccessors(), which breaks down how to access the data in a JSON structure. Checking the JSON object in the Locals Window reveals that it consists of a collection of collections. Checking the TypeName of the item in the Immediate Window also reveals that item is indeed a collection' ?TypeName(Item) Collection PrintJSONAccessors JSON, "?JSON" The code will output the correct way to access the data Here is how you can access the items of the Collection For Each Item In JSON Sheets(1).Cells(i, 1).Value = Item(1) ' Items reference as an example Sheets(1).Cells(i, 2).Value = Item(2) Sheets(1).Cells(i, 3).Value = Item(3) Sheets(1).Cells(i, 4).Value = Item(4) Sheets(1).Cells(i, 5).Value = Item(5) i = i + 1 Next I would write a function to convert the JSON data into an Array Public Sub exceljson() Dim http As Object Set http = CreateObject("MSXML2.XMLHTTP") http.Open "GET", "https://api.bitfinex.com/v2/candles/trade:5m:tEOSUSD/hist?start=1535760000000&end=1538265600000&sort=1", False http.Send Dim results As Variant results = BitfinexTextToArray(http.responseText) Worksheets(1).Range("A1").Resize(UBound(results), UBound(results, 2)).Value = results MsgBox ("complete") End Sub Function BitfinexTextToArray(responseText As String) As Variant Dim item As Variant, JSON As Object Dim MaxColumns As Long Set JSON = ParseJson(responseText) For Each item In JSON If item.Count > MaxColumns Then MaxColumns = item.Count Next Dim results As Variant ReDim results(1 To JSON.Count, 1 To MaxColumns) Dim c As Long, r As Long For Each item In JSON r = r + 1 For c = 1 To item.Count results(r, c) = item(c) Next Next BitfinexTextToArray = results End Function
Access Values In Nested Array in JSON response
I have a multidimensional JSON array returned via a web request (http://www.coincap.io/history/365day/BTC). I want to cycle through the 2nd entry and retrieve its nested values. If this was a normal array, I'd use: For Each item In response logic, logic, logic currentRow = currentRow + 1 Next This web request returns a JSON-response with 3 entries: market_cap, price, and volume. I just want to cycle through response(1) and get the price values. Each entry in price contains two keys, 0 and 1. I would imagine that I could accomplish this by doing For Each item in response(1) Cells(currentRow, 1).Value = item(0) Cells(currentRow, 2).Value = item(1) currentRow = currentRow + 1 Next I've also considered For Each item in response("price"). Neither works.
Sub Tester() Dim json As String Dim sc As Object Dim o, n, i, p Set sc = CreateObject("scriptcontrol") sc.Language = "JScript" json = HttpGet("http://www.coincap.io/history/365day/BTC") sc.Eval "var obj=(" & json & ")" 'evaluate the json response 'add a couple of accessor functions sc.AddCode "function numPrices(){return obj.price.length;}" sc.AddCode "function getPrice(i){return obj.price[i];}" n = sc.Run("numPrices") For i = 0 To n - 1 p = Split(sc.Run("getPrice", i), ",") Debug.Print i, p(0), p(1) Next i End Sub Function HttpGet(url As String) As String Dim oHTML As Object Set oHTML = CreateObject("Microsoft.XMLHTTP") With oHTML .Open "GET", url, False .send HttpGet = .responsetext End With End Function
Loop until website has no additional JSON arrays to parse
I am looking for a loop function/syntax that will allow my loop to cease once the website I am pulling JSON arrays from has no additional arrays left to parse (variable / unknowable number of arrays). Thank you for the insight. sheetCount = 1 i = 1 urlArray = Array("URL array list") Dim MyRequest As Object Set MyRequest = CreateObject("WinHttp.WinHttpRequest.5.1") Dim MyUrls MyUrls = urlArray Dim k As Long Dim Json As Object For k = LBound(MyUrls) To UBound(MyUrls) With MyRequest .Open "GET", MyUrls(k) .Send Set Json = JsonConverter.ParseJson(.ResponseText) Do Until ''[NEED HELP HERE] Sheets("Sheet" & sheetCount).Cells(i, 1) = Json("cars")(i)("carType") Sheets("Sheet" & sheetCount).Cells(i, 2) = Json("cars")(i)("fare")("carprice") i = i + 1 Loop End With sheetCount = sheetCount + 1 Next
You are missing the UBound function. Other notes No code without Option Explicit, period. No exceptions. Make small functions that do one thing only. Add references to the libraries you use instead of using CreateObject. It will make your life a lot easier because this way you get compile-time type checking and Intellisense. It's safer to use the Exists() method to check if a dictionary key exists before you try to access it. Trying to access a non-existing key will throw a run-time error. I'm silently assuming that you are using https://github.com/VBA-tools/VBA-JSON. This should be close enough: Option Explicit Function GetJson(ByVal url As String) As Dictionary With New WinHttpRequest ' see http://stackoverflow.com/a/3119794/18771 .Open "GET", url .Send Set GetJson = JsonConverter.ParseJson(.ResponseText) End With End Function Sub FillCarInfo(data As Dictionary, sheet As Worksheet) Dim i As Integer, car As Dictionary For i = 0 To UBound(data("cars")) - 1 Set car = data("cars")(i) ' you probably should use If car.Exists("carType") Then sheet.Cells(i, 1) = car("carType") sheet.Cells(i, 1) = car("fare")("carprice") Next i End Sub Sub FillMultipleCarInfo(urls As Variant, book As Workbook) Dim i As Integer, data As Dictionary, sheet As Worksheet For i = 0 To UBound(urls) - 1 Set data = GetJson(urls(i)) Set sheet = book.Sheets(i + 1) FillCarInfo data, sheet Next i End Sub Usage Dim myUrls As Variant myUrls = Array("URL array list") FillMultipleCarInfo myUrls, ActiveWorkbook