How to get data from JSON nested arrays in excel vba-json - json

I'm preparing some kind of software working with Excel with an API, and I'm using vba-json library, and I dont know how to get data from nested arrays on JSON.
I've tryied some tutorials and another similar questions that I fond here. But every time I try I get a different error. Runtime error 5, 9, 13. Tryied different ways to accés the data but everytime I get error when I get into an array.
Set MyRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
MyRequest.Open "GET", "https://pokeapi.co/api/v2/pokemon/ditto/?fbclid=IwAR2pJwAgODOlI-Gdn8pH-RDFCcUfQWiYLZIVCnP8e-V_9gEwYymqRldpiFk"
MyRequest.Send
Dim Json As Object
Set Json = JsonConverter.ParseJson(MyRequest.ResponseText)
MsgBox Json("stats")("id")(0)("base_stat")
I'd like to get the data from the selected array to later be able to work with it, for example from
("stats")("id")(0)("base_stat")
get
48
The Json source is on the code.

So, with JSON the [] denotes a collection you can For Each over and access by index, the {} indicates dictionaries you can For Each the dict keys of, or access items by key.
You can get a feel for the structure by pasting it into a json viewer such as this. You will need to familiarise yourself with reading json but you will see that, for that value you want, it has a path of:
json("stats")(1)("base_stat")
Note: The indexing starts at one for collections in VBA JSON though it is displays 0 in the viewer.
Reading the structure:
Option Explicit
Public Sub test()
Dim Json As Object
With CreateObject("WinHttp.WinHttpRequest.5.1")
.Open "GET", "https://pokeapi.co/api/v2/pokemon/ditto/?fbclid=IwAR2pJwAgODOlI-Gdn8pH-RDFCcUfQWiYLZIVCnP8e-V_9gEwYymqRldpiFk"
.send
Set Json = JsonConverter.ParseJson(.responseText)
End With
MsgBox Json("stats")(1)("base_stat")
End Sub
Note there are various answers on StackOverflow which provide code that will list the access paths to every item in a json structure. In particular, I remember this great answer from #tinman here. It's not a substitute for learning to read JSON but an excellent tool for aiding and checking your understanding.

Related

VBA-JSON: Add entry to Existing File

I'm using excel to modify existing JSON with the VBA-JSON library and I'm effectively trying to do what .push from javascript does, adding another entry to the nested array.
There's this previously posted question which illustrates what I'm trying to do but in the scope of creating a JSON file.
VBA-JSON Create nested objects
The accepted answer while helpful, doesn't show me how to add to what I already have without rebuilding it entirely. I can picture a mess of loops to parse my existing file into strings, then do something similar to what is in the post. I'm curious if there's another way to do it.
'download json
Set json = JsonConverter.ParseJson(H.responseText)
Debug.print json(1)("entries")(1)("Date")
'2019-09-25
json(1)("entries")(2)("Date") = "2019-09-26"
'error 9 Subscript out of Range
'upload json
[
{
"Entries": [
{
"Date": 2019-09-25,
"a": 1,
"b": 2
}
]
}
]
I'm able to access and modify existing entries but not add to it. I'm guessing this is because the library parses it as a defined array rather than variable? Any ideas on a simple solution or will I have to deconstruct my file into dictionaries/collections and rebuild it first?
VBA Json is really just a cheap (and effective) converter/deconverter of a json string into a nested set of dictionaries and collections. So you don't have to "deconstruct [your] file into dictionaries/collections and rebuild it" since... it already is. This is why it's necessary to add in the Microsoft Scripting Runtime library to use it.
The struggle you are dealing with is that you are treating every object in your json object as a dictionary. Instead you want to add(pop) to the entries collection. A good way to keep these separate is that in VBA JSON (as far as I've seen) if an object is a key/value pair, then it's a Dictionary and if it's just an object without a key then it's a Collection. I'm certain there is more nuance there, but it works well in this scenario.
Consider:
Sub test()
Dim Json As Object
Set Json = JsonConverter.ParseJson("[{""Entries"":[{""Date"": 2019-09-25,""a"": 1,""b"": 2}]}]")
Dim entry1 As Object
Set entry1 = Json(1)("Entries")
Stop '<--inspect Locals and see that we have a Collection here
'Add to the collection (different then adding to a dictionary)
'We will add a dictionary to the collection though
Json(1)("Entries").Add New Dictionary
'Now add to the dictionary.
Json(1)("Entries")(2).Add "Date", "2019-09-26"
Stop
Debug.Print JsonConverter.ConvertToJson(Json)
'Alternatively you could create the dictionary and add your keys, then `pop` your entries
Dim Entry As Dictionary
Set Entry = New Dictionary
Entry.Add "Date", "2019-09-26"
Entry.Add "a", "2"
Entry.Add "b", "3"
Json(1)("Entries").Add Entry
Debug.Print JsonConverter.ConvertToJson(Json)
End Sub
This should spit out what you are after (I think):
[{"Entries":[{"Date":"2019-09-25","a":1,"b":2},{"Date":"2019-09-26"}]}]
I guess another way to think through this is that if we want to add a new array to our Entries then we have to add a new Dictionary object to the Entries collection. Then we can add into the dictionary our key/value pairs like Date, a, and b.

VBA-JSON returning only 32,767 characters on API call

I am utilizing the latest VBA-JSON file, as of 2018 10 11, from here:
https://github.com/VBA-tools/VBA-JSON/releases
While using the following code I am able to return data to the worksheet:
Dim httpObject As Object
Set httpObject = CreateObject("MSXML2.XMLHTTP")
sURL = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?**API Key... I can provide if necessary**"
sRequest = sURL
httpObject.Open "GET", sRequest, False
httpObject.send
sGetResult = httpObject.responseText
Set oJSON = JsonConverter.ParseJson(sGetResult)
Range("A1").Value = sGetResult
I have determined that it is returning 32,767 characters (not all of the data).
I have seen similar questions here on Stack Overflow that relate the issue to setting specific JSON options, but I do not see the same JSON options in the JSON file that I am using.
I've made changes from Integer to Long, but that has had no effect.
Smile :-) I actually built a crypto tracker at the start of the year (and then had to get some real work done so it's been idle).
At the core was a JSON retriever and parser I wrote a few years back (with the help of StackOverflow no doubt). I'd post the zip files here but I don't think we're allowed to do that.
I'm going to submit a question in a few minutes asking someone to turn the following into an opensource / free set of VBA for anyone to use. I've seen several questions along these lines (about JSON Parsing).
So, if you're interested -- you may find help here: http://davidnickell.net/excel-json-parser/
Good luck and happy parsing.

VBA getting values from a collection?

I am very new to VBA and I can not figure out how to get values from a Collection.
This is my code:
Dim p As Object
Set p = JSON.parse(Response.Content)
Dim links As Object
Set links = p.Item("links")
In the debugger for "links" I see:
I am using this library to parse json : http://www.ediy.co.nz/vbjson-json-parser-library-in-vb6-xidc55680.html
The part I have in json is:
"links":[
{
"rel":"next",
"href":"www.google.com"
}
]
How can I get the value of "rel" here?
Don't forget the bang operator, designed for collection access by key:
links(1)!rel
or:
links(1)![rel] 'When there are spaces or reserved words.
I will answer my own question:
links(1).Item("rel")
worked...
Regards..
Using JavaScript features of parsing JSON, on top of ScriptControl, we can create a parser in VBA which will list each and every data point inside the JSON. No matter how nested or complex the data structure is, as long as we provide a valid JSON, this parser will return a complete tree structure.
JavaScript’s Eval, getKeys and getProperty methods provide building blocks for validating and reading JSON.
Coupled with a recursive function in VBA we can iterate through all the keys (up to nth level) in a JSON string. Then using a Tree control (used in this article) or a dictionary or even on a simple worksheet, we can arrange the JSON data as required.
You can see the full VBA code here

Understanding VBJSON class set up in Excel 2010

I have downloaded and set the JSON parser for VB6 from this website:
VB-JSON
I cannot understand how this module works. I successfuly set it in Excel 2010 and I think I also understand the JSON format but I don't know how this class extracts the items. I tried to parsed the following text in the JSON format
{"realms":[{"type":"pvp","population":"low","queue":false,"wintergrasp":{"area":1,"controlling-faction":1,"status":0,"next":1356724174636},"tol-barad":{"area":21,"controlling-faction":1,"status":0,"next":1356723246779},"status":true,"name":"Kor'gall","slug":"korgall","battlegroup":"Cruelty / Crueldad","locale":"en_GB","timezone":"Europe/Paris"},{"type":"pve","population":"medium","queue":false,"wintergrasp":{"area":1,"controlling-faction":0,"status":0,"next":1356724425638},"tol-barad":{"area":21,"controlling-faction":0,"status":0,"next":1356723369780},"status":true,"name":"Alonsus","slug":"alonsus","battlegroup":"Cruelty / Crueldad","locale":"en_GB","timezone":"Europe/Paris"}]}
A browser will return this content when the following address is used:
Alonsus, Kor'gall
I wrote a code similar to this
Dim objJSON As Object
...
strData = objJSON.Item("Realms")(1).Item("Type")
but it causes errors: "Object variable or With block variable not set". I expected to get "pve" value. I am confused because it starts with an object name "realms" followed by an Array. The array is supposed to be returned as a collection. I would be grateful for any help with that.
Thanks
set objJSON = JSON.Parse(jsonFromUrl)
strData = objJSON.Item("realms").Item(1).Item("type")
Keys inside json is case-sensitive.

Use ScriptControl to parse JSON in VBA: transform result to dictionaries and collections

I would like to use Microsoft ScriptControl to parse a JSON string in VBA, and then transform the resulting Object into Dictionary and Collection objects. I already know how to do the parsing with ScriptControl, but cannot figure out how to map the result into the Dictionary and Collection classes. I'm guessing that if I could figure out how to loop through the properties of an Object this would become clear...
Dim sc As ScriptControl
Dim obj As Variant
Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
Set obj = sc.Eval("("+json+")") ' json is a string containing raw JSON
' Now what?
By the way, I've used the vba-json library to get the output in terms of Dictionaries and Collections, but I find this library somewhat slow. It does not use ScriptControl.
EDIT: I found a discussion of getting object properties in this post.
Using JavaScript features of parsing JSON, on top of ScriptControl, we can create a parser in VBA which will list each and every data point inside the JSON. No matter how nested or complex the data structure is, as long as we provide a valid JSON, this parser will return a complete tree structure.
JavaScript’s Eval, getKeys and getProperty methods provide building blocks for validating and reading JSON.
Coupled with a recursive function in VBA we can iterate through all the keys (up to nth level) in a JSON string. Then using a Tree control (used in this article) or a dictionary or even on a simple worksheet, we can arrange the JSON data as required.
VBA Code:http://ashuvba.blogspot.in/2014/09/json-parser-in-vba-browsing-through-net.html
loop
This will help you to loop - add a myitem(n) method in javascript
from there you can map through VB code.