I have JSON data string from which I try to extract the highest value of "id" without iterating.
This is the JSON data string:
"ball_coordinates": [
{
"id": 3938706,
"fixture_id": 18795544,
"period_id": 4644037,
"timer": "17:20",
"x": "106",
"y": "57"
},
{
"id": 3938771,
"fixture_id": 18795544,
"period_id": 4644037,
"timer": "18:17",
"x": "15",
"y": "75"
},
{
"id": 3939282,
"fixture_id": 18795544,
"period_id": 4644037,
"timer": "28:47",
"x": "21",
"y": "19"
},
{
"id": 3938083,
"fixture_id": 18795544,
"period_id": 4644037,
"timer": "3:28",
"x": "8",
"y": "77"
}
]
},
The highest id is 3939282.
In the post below I noticed it is possible to count the items in a part of a JSON string:
size of an array excel - json vba parser
If I change var.Count to var.Max it works too.
If I try to implement this method in my own Excel VBA code in the way below, it gives an error at line two (starting with Set myvar).
Dim myvar As Object
Set myvar = item("ball_coordinates")("id")
Debug.Print myvar.Count
Debug.Print WorksheetFunction.Max(myvar)
The error is: Run-time error 5: Invalid procedure call or argument.
I have the JsonConvertor-code activated in this workbook which runs fine.
I suppose the reason is that the id's are spread over all elements and not within one element as is the case in the other post.
Is there any way to overcome this?
Thanks a lot!
EDIT:
The reason for my question is that I try to increase the speed of my code. If I use the code below with iteration it takes 9 seconds to process 30k ball_coordinates.
highest_bal_id = 0
bal_timer = "NA"
bal_x = "NA"
bal_y = "NA"
For Each bal In item("ball_coordinates")
bal_id = bal("id")
If bal_id > highest_bal_id Then
bal_timer = bal("timer")
bal_x = bal("x")
bal_y = bal("y")
highest_bal_id = bal_id
End If
Next
EDIT 2:
I also tried the alternative code below to see if this is faster. Although I do not succeed to access item("ball_coordinates")("id") based on the highest_ball_id. I do not know if it is possible to access it as a dictionary or collection with a key based on highest_ball_id.
teller = 1
For Each bal In item("ball_coordinates")
temp_array(teller) = bal("id")
teller = teller + 1
Next
highest_ball_id = WorksheetFunction.Max(temp_array)
Debug.Print item("ball_coordinates")("id"); highest_ball_id
EDIT 3
The json data string is nesting from a larger string. The data is from an API and generated with this code:
Dim http As Object, json As Object, i As Integer, item As Object
Dim APIString As String
Set http = CreateObject("MSXML2.XMLHTTP")
APIString = "https://api.com/livescores/inplay?api_token=__&include=periods;scores;participants;ballCoordinates"
http.Open "GET", APIString, True
http.send
Set json = ParseJson(http.responseText)
For Each item In json("data")
'read every item for periods, scores, participants, ballCoordinates
Next
The complete data has this structure:
{
"data": [
{
"id": 18796712,
"sport_id": 1,
"league_id": 2451,
"periods": [
{
"id": 4646720,
"fixture_id": 18796712
}
],
"scores": [
{
"id": 12200589,
"fixture_id": 18796712
},
{
"id": 12200590,
"fixture_id": 18796712
},
{
"id": 12200545,
"fixture_id": 18796712
},
{
"id": 12200546,
"fixture_id": 18796712,
}
],
"participants": [
{
"id": 24401,
"sport_id": 1
}
},
{
"id": 11978,
"sport_id": 1
}
}
],
"ball_coordinates": [
{
"id": 4549595,
"fixture_id": 18796712,
"period_id": 4646720,
"timer": "03:25",
"x": "39",
"y": "25"
},
{
"id": 4549532,
"fixture_id": 18796712,
"period_id": 4646720,
"timer": "03:20",
"x": "39",
"y": "25"
},
{
"id": 4549466,
"fixture_id": 18796712,
"period_id": 4646720,
"timer": "03:14",
"x": "39",
"y": "25"
},
{
"id": 4549422,
"fixture_id": 18796712,
"period_id": 4646720,
"timer": "03:11",
"x": "39",
"y": "25"
}
]
},
{
"id": 18560614,
"sport_id": 1,
"league_id": 603,
"periods": [
{
"id": 4646650,
"fixture_id": 18560614
}
],
"scores": [
{
"id": 12200402,
"fixture_id": 18560614
},
{
"id": 12200392,
"fixture_id": 18560614
},
{
"id": 12200394,
"fixture_id": 18560614
},
{
"id": 12200401,
"fixture_id": 18560614
}
],
"participants": [
{
"id": 4190,
"sport_id": 1
},
{
"id": 286,
"sport_id": 1
}
}
],
"ball_coordinates": [
{
"id": 4549597,
"fixture_id": 18560614,
"period_id": 4646650,
"timer": "31:23",
"x": "0.42",
"y": "0.24"
},
{
"id": 4549579,
"fixture_id": 18560614,
"period_id": 4646650,
"timer": "31:20",
"x": "0.42",
"y": "0.24"
},
{
"id": 4549549,
"fixture_id": 18560614,
"period_id": 4646650,
"timer": "31:19",
"x": "0.61",
"y": "0.19"
},
{
"id": 4549483,
"fixture_id": 18560614,
"period_id": 4646650,
"timer": "31:14",
"x": "0.61",
"y": "0.19"
},
{
"id": 4549472,
"fixture_id": 18560614,
"period_id": 4646650,
"timer": "31:13",
"x": "0.41",
"y": "0.81"
}
]
}
]
}
ball_coordinateswould be aCollectionobject (which does have aCountproperty) containing oneScripting Dictionaryobject per contained item. The only way to get the max. value (or any other measure) across all of the "id" key values in those dictionaries is to loop over them.