I've imported the VBA JSON library into my VBA project but I can't get it to create the JSON object properly. I've fallen at the first hurdle.
Even the example code that they give isn't working:
Sub test()
Dim Json As Object
Set Json = JsonConverter.ParseJson("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")
' Json("a") -> 123
' Json("b")(2) -> 2
' Json("c")("d") -> 456
MsgBox Json("c")("e") = 789
End Sub
This gives the following answers:
a
2
456
null
I've selected the Microsoft Scripting Runtime library and added the VBA Dictionary class.
I'm getting the expected results.
Sub TestJson()
Dim Json As Object
Set Json = JsonConverter.ParseJson("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")
Debug.Print Json("a") '--> 123
Debug.Print Json("b")(2) '--> 2
Debug.Print Json("c")("d") '--> 456
Json("c")("e") = 789 'create new key and value under "c"
Debug.Print Json("c")("e") '--> 789
End Sub
Be very careful using the Watch window when dealing with Dictionary objects: just having an active watch on a dictionary key can cause that key to get added.
Related
I have an excel cell value [[{"Name":Ashwin ,"Age":64}],[],[{"Name":Shakur ,"Age":64,"Gender":Male}]]
I need to display the value of gender in cells.
Please find below my code:
Option Explicit
Sub ExampleSplit()
Dim s As String, vx() As String
My_array = Worksheets("sheet1").Cells(1, 1)
vx = Split(My_array, "{")
Array_need = "{" & Split(vx(UBound(vx)), "}")(0) & "}"
Set Jsonobject = JsonConverter.ParseJson(Array_need)
For Each Item In Jsonobject
If Item = "Gender" Then
Worksheets("sheet1").Cells(1, 2) = Item("Gender")
End If
Next
End Sub
After running sucessfuly,value "Male" should be in worksheets("sheet1").cells(1,2).But for me it was throwing "type mismatch"
I wrote PrintJSONAccessors() to answer a similar question: Using VBA and VBA-JSON to access JSON data from Wordpress API. My sub routine prints the proper way to access the json data to the Immediate Window.
The sample code is not valid JSON. It is missing double quotes around its string values.
[[{"Name":Ashwin ,"Age":64}],[],[{"Name":Shakur ,"Age":64,"Gender":Male}]]
This is the valid version:
[[{"Name":"Ashwin" ,"Age":64}],[],[{"Name":"Shakur" ,"Age":64,"Gender":"Male"}]]
Here is how I prepare to extract the JSON data:
Sub Prep()
Dim Data As Variant
Data = Worksheets("sheet1").Cells(1, 1).Value
Set Data = JsonConverter.ParseJson(Data)
PrintJSONAccessors Data, "Data"
Stop
End Sub
I put the Stop in the code so that I can test output in the Immediate Window.
Notice the data is a Dictionary inside a Collection inside another Collection.
Getting Error on "Excel VBA Run-time error '13': Type mismatch" using JsonConverter
my JSON
{"gstin":"33A","fp":"062020","b2b":[{"ctin":"33B","cfs":"Y","cfs3b":"Y","inv":[{"itms":[{"num":1801,"itm_det":{"csamt":0,"samt":83.97,"rt":18,"txval":933,"camt":83.97}}],"val":1050.94,"inv_typ":"R","pos":"33","idt":"10-06-2020","rchrg":"N","inum":"C3/071","chksum":"60a9044051e8b6ba1122f614143a4d1236b1399872b0ea408df6a82ba832253d"}],"fldtr1":"25-Jul-20","flprdr1":"Jun-20"}]}
my Code
Private Sub CommandButton1_Click()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Title = "Select Json files"
.AllowMultiSelect = False
If .Show() Then
Filename = .SelectedItems(1)
Dim content As String
Dim iFile As Integer: iFile = FreeFile
Open Filename For Input As #iFile
content = Input(LOF(iFile), iFile)
Dim products As Object, Item
Set products = JsonConverter.ParseJson(content)
i = 1
For Each Item In products
Debug.Print Item("gstin")
'Cells(i, 1) = Item("ctin")
'i = i + 1
Next
Close #iFile
End If
End With
End Sub
also need to implement root and keys (like: gstin, ctin, csamt, inum)
Thanks
Please limit to a single question. Your current error is because products is a dictionary and the keys are strings. You cannot do Item("gstin") as Item is a string. You would want initially products(Item) but won't be able to just use Debug.Print as not all the associated values in the dictionary are simple datatypes e.g. products("b2b") will return a collection and lead to a RTE 450 error due to incorrect syntax.
You will need to develop your code to test for which datatype is returned from the dictionary and any nested levels. [] indicates a collection you can For Each over, whereas {} indicates a dictionary. There are lots of examples on SO to help you with this and code examples that will write the entire structure out for you.
I am trying to pull JSON values from a URL that I am working with at the moment. I may have done something like this before but I dont know what I'm missing here.
Here is the URL - https://eu-offering.kambicdn.org/offering/v2018/888/listView/golf.json?lang=en_GB&market=GB&client_id=2&channel_id=1&ncid=1568916879040&useCombined=true
And an image for clarity of what is needed to be extracted.
I ran a test using Tinman's approach as can be found here - How to get, JSON values to Work in VBA-JSON? , but i can't even apply his function, PrintJSONAccessors(), here
Public Sub exceljson()
Dim http As Object
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET",
"https://eu-offering.kambicdn.org/offering/v2018/888/listView/golf.json?lang=en_GB&market=GB&client_id=2&channel_id=1&ncid=1568916879040&useCombined=true", 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
I need help with pulling the following item values from each of the JSON "event"
1. "englishName"
2. "participant"
3. "oddsFractional"
NOTE: my example uses the JsonConverter library and requires you to add a reference to the Microsoft Scripting Runtime to access the Dictionary object.
I set up a test file with JSON loaded from your URL above. After parsing the JSON data, the exercise becomes understanding how the various levels are nested and what type of data structure is being used. In your JSON, it's a mix of Collection, Array, and Dictionary in various combinations. My example below shows how you have to stack up these nested references to get the data you're looking for.
Review the information in this answer to understand how the JSON is parsed into a hierarchical data structure.
Option Explicit
Public Sub test()
Dim fileNum As Long
fileNum = FreeFile()
Dim filename As String
filename = "C:\Temp\testdata.json"
Dim jsonInput As String
Open filename For Input As #fileNum
jsonInput = Input$(LOF(fileNum), fileNum)
Close fileNum
Dim json As Object
Set json = ParseJson(jsonInput)
Debug.Print " English Name = " & json("events")(1)("event")("englishName")
Debug.Print " Participant = " & json("events")(1)("betOffers")(1)("outcomes")(2)("participant")
Debug.Print "Odds Fractional = " & json("events")(1)("betOffers")(1)("outcomes")(2)("oddsFractional")
End Sub
An even better solution will be to create an intermediate variable and then loop over the contents in an array (or collection or dictionary).
I am using ACCESS VBA to parse Json.
It is getting the value that are in the 1st curly braces.
But anything within the 2nd curly gives an error
Wrong number of arguments of invalid property assignment
JSON:
[
{
"Number": 1,
"Name": "John Doe",
"DateOfB": "2018-05-05",
"Place": {
"Pl": 4,
"Name": "England"
}
}
]
I am able to get the values for Number, Name and DateofB.
But I'm unable to get the value for Place for that I am getting the error.
I am using the widly available clsJsonParser module in my VBA application.
Following the sample in the clsJsonParser this is what works for you:
Public Sub TestJSON()
Dim JP As JSONParser
Set JP = New JSONParser
JP.Filename = "c:\myJson.txt"
Dim varData As Variant
Set varData = JP.Parse
Debug.Print varData(1)("Number")
Debug.Print varData(1)("Name")
Debug.Print varData(1)("DateOfB")
'You have to explicitely use a Dictionary type here to store the place.
Dim placeDictionary As Scripting.Dictionary
Set placeDictionary = varData(1)("Place")
'Output all keys and items of the place dictionary:
Dim index As Long
For index = 0 To placeDictionary.Count - 1
Debug.Print placeDictionary.Keys(index), placeDictionary.Items(index)
Next index
'Access place dictionary items by name:
Debug.Print placeDictionary("Pl")
Debug.Print placeDictionary("Name")
End Sub
You have to reference the Microsoft Scripting Runtime to introduce the type Scripting.Dictionary.
Code Below Worked:
For Each Appt In JSON
rs.AddNew
rs!Appt_ID = Appt("Number")
rs!ClientFullName = Appt("Name")
rs!Appt_Date = Appt("DateOfB")
rs!TC_Center = Appt("Place")("Pl")
rs.Update
Next
I am using a vba json parser : https://github.com/VBA-tools/VBA-JSON . I want to loop over the elements in the B array but I am unsure how to do this. e.g.
Set Json = JsonConverter.ParseJSON("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")
If you want to get back the number of elements in B how do you do this?
You get back the actual value by doing the following : Json("a")
The docs for the source vba-json state:
parse JSON and create Dictionary/Collection
So you will get back one of those objects. This seems to work:
Sub testJson()
Dim Json As Object
Set Json = JsonConverter.ParseJson("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")
Debug.Print Json("a") ' -> 123
Debug.Print Json("b")(2) ' -> 2
Debug.Print Json("c")("d") ' -> 456
Json("c")("e") = 789
Dim var As Object
' Get the object from Json
Set var = Json("b")
' Both Dictionary and Collection support the Count property
Debug.Print var.Count
Dim elem As Variant
For Each elem In var
Debug.Print elem
Next elem
Debug.Print JsonConverter.ConvertToJson(Json)
' -> "{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456,""e"":789}}"
End Sub
The "b" in the Json example returns a collection but for "c" you would get back a dictionary.