Using Access VBA to read JSON data - json

I'm using the following VBA subroutine to read JSON data from a website:
Sub DistanceRetrieve()
Dim url As String, attempts As Integer, strResponse As String, strLatitude As String
Dim WinHttpReq As Object, Json As Object
url = "https://distances.dataloy.com/port/port?filter=portName(EQ)BERGEN"
attempts = 3
Set WinHttpReq = CreateObject("MSXML2.XMLHTTP.6.0")
On Error GoTo TryAgain
TryAgain:
attempts = attempts - 1
Err.Clear
If attempts > 0 Then
With WinHttpReq
.Open "GET", url, False
.SetRequestHeader "Content-Type", "application/json"
.Send
If .Status = 200 Then
strResponse = .ResponseText
Set Json = JsonConverter.ParseJson(strResponse)
strLatitude = Json("latitude")
End If
End With
Else
MsgBox ("A4. No internet connection is available.")
End If
End Sub
Scripting Runtime and WinHTTP Services are referenced and Json Converter is imported. The subroutine, in its core, is found on many sites on the internet. After I run it, strResponse contains just two characters; "[, while it should contain the following string:
[ { "portName": "BERGEN", "countryCode": "NO", "countryName": "Norway", "locationCode": "BGO", "timezone": "Europe/Oslo", "latitude": 60.392039, "longitude": 5.306605, "key": 104146}]
Also, Json("latitude") statement gives "Invalid procedure call or argument" error message. Am I missing somthing?
Best regards.
Said

Related

10001 - JSON parse error for SuccessFactors OData API

I was trying to pull SuccessFactors data by VBA.
And I was able to pull data by metadata form.
Yet, when I try to convert this into JSON, I kept getting below error...
Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(JsonString, json_Index, "Expecting '{' or '['")
here is my code...
(I put demo instance for SuccessFactors in here)
Sub GetData()
Dim httpReq As New XMLHTTP60
Dim strURL As String
strURL = "https://api55.sapsf.eu/odata/v2/EmpJob?$top=10"
Set httpReq = CreateObject("MSXML2.XMLHTTP")
httpReq.Open "GET", strURL, False
httpReq.Open "GET", strURL, False, "sfadmin#SFPART066783", "PASSWORD"
httpReq.send
Debug.Print httpReq.responseText
Dim jsonObj As Object
Set jsonObj = JsonConverter.ParseJson(httpReq.responseText)
End Sub

Excel VBA-JSON: How do loop through an array inside a JSON object?

Consider this JSON object:
{
"fileName": "Batch_01032023_SakerItemData.xlsx",
"fileLocation": "C:\\Temp",
"message": "There are 3 errors. Please correct and try again.",
"error": [
"{Item} failed validation:Item is required.:8",
"{Type} failed validation:Type is required.:8",
"{Class} failed validation:Class is required.:8"
]
}
I am using the JsonConverter from this repo https://github.com/VBA-tools/VBA-JSON
Consider this VBA code:
Dim jsonObject As Object, item As Object
Dim objHTTP As Object
Dim url As String
Dim result As String
Dim async As Boolean
Dim body As String
body = "{""fileLocation"":""{fileLocation}""}"
body = Replace(body, "{fileLocation}", Replace(fileLocation, "\", "\\"))
Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
With objHTTP
.Open "POST", url, async
.SetRequestHeader "Content-Type", "application/json"
.SetRequestHeader "Accept", "application/json"
.SetRequestHeader "Authorization", "Basic " + _
Base64Encode(authUser + ":" + authPassword)
.Send body
.waitForResponse
result = .responseText
End With
Set jsonObject = ParseJson(result)
*** What is the syntax here to loop through error object? ****
For Each item In jsonObject("error")(1)
Next
this line Set jsonObject = ParseJson(result) does not throw an error and seems to work, yet when I get to the 'for each' loop, I get Error # 424 'Object Required'.
My question is this: How can I loop through the 'error' array in the 'jsonObject' so that I can display the validation errors to the user? The error array is dynamic.
The key error returns a Collection, so first assign it to a variable declared as Collection...
Dim col As VBA.Collection
Set col = jsonObject("error")
Then loop through each item in the collection...
Dim itm As Variant
For Each itm In col
Debug.Print itm
Next itm

Using Access VBA to read JSON data (part two)

The following subroutine reads Json data from an internet site:
Sub DistanceRetrieve()
Dim url As String, Response As String
Dim PointCordinate As String
Dim WinHttpReq As Object, Json As Object, Paths As Object, Item As Object, NextItem As Object,
Points As Object
Set WinHttpReq = CreateObject("MSXML2.XMLHTTP.6.0")
With WinHttpReq
url = "https://distances.dataloy.com/route/route?point=" & Latitude1 & "," & Longitude1 &
"&point=" & Latitude2 & "," & Longitude2 & "&block_sc=" & BlockSC & "&block_nw=" & BlockNW
&"&block_ne=" & BlockNE
.Open "GET", url, False
.SetRequestHeader "Content-Type", "application/json"
.SetRequestHeader "X-API-Key", "DnqL8TJbh77wn0DphKhhI6GPOy3fnKDt2fDUMB8j"
.Send
If .Status = 200 Then
Response = .ResponseText
Set Json = JsonConverter.ParseJson(Response)
Set Paths = Json("paths")
For Each Item In Paths
Distance = Item("distance")
Set Points = Item("points")
For Each NextItem In Points
PointCoordinate = NextItem("coordinates")
If PointCoordinate = SuezCanalCoordinate Then
MsgBox ("Sues Canal is on route.")
End Sub
End If
Next
MsgBox ("Sues Canal is not on route.")
End Sub
Next
End If
End With
End Sub
N.B. Some variables are declared as public.
The "For Each NextItem In Points" statement gives "Object required" error message when the code is run.
Hereinafter is the first part of the Json data:
{ "info" : { "copyrights" : [ "Viku AS"], "took" : 1346 }, "paths" : [ { "distance" : 10289.034929805617, "bbox" : [ -10.026282, 1.124421, 113.648011, 60.180576], "points" : { "coordinates" :[[4.960373,60.180576],[4.962496,60.162612],[4.986241,60.143381],[4.944009,60.137372],[4.944009,60.137372],[4.10086,59.45105],[4.100343,59.002301],[1.42238,50.973884],[1.328024,50.868336],[1.308167,50.854352],[1.16305,50.752155],[1.065639,50.683556],[0.919434,50.580593],[0.602589,50.517847],[-0.070224,50.384606],[-0.376109,50.333315],[-1.053553,50.219721],[-1.730997,50.106127],[-2.408441,49.992533],[-2.88957,49.908579],[-3.209387,49.787494],[-3.806258,49.561516],[-4.403129,49.335538],[-5.0,49.109559],[-5.51017,48.916407],[-5.861724,48.642143],[-6.169181,48.246339],[-6.476639,47.850535],[-6.784096,47.454732],[-7.091553,47.058928],[-7.39901,46.663124],[-7.706467,46.26732],[-8.013925,45.871517],[-8.321382,45.475713],[-8.628839,45.079909],[-8.936296,44.684106],[-9.243753,44.288302],[-9.55121,43.892498],[-9.858668,43.496694],[-9.891568,43.45434],[-10.023932,43.260722],[-10.026282,42.88182],[-10.026186,42.46553],[-10.026082,42.015288],[-10.025979,41.565047],[-10.025875,41.114806],[-10.025771,40.664564],[-10.025667,40.214323],[-10.025564,39.764081],[-10.02546,39.31384],[-10.025356,38.863598],[-10.025356,38.69584],[-9.998078,38.603524],[-9.908628,38.296362],[-9.78081,37.857447],[-9.652993,37.418532],[-8.509321,36.452241],[-7.973851,36.329996],[-7.438382,36.20775],[-6.902912,36.085504],[-6.367442,35.963259],[-6.200541,35.925156],[-6.100124,35.925653],[-5.749613,35.937037],[-5.608748,35.93671],[-5.551674,35.951129],[-5.508509,35.962488],[-5.469502,35.972753],[-5.427,35.983562],[-5.072639,36.028626],[-4.523336,36.098481],[-3.974033,36.168336],[-3.42473,36.238191],[-2.875427,36.308045],[-2.326124,36.3779],[-2.268051,36.385285],[-2.188115,36.395701],[-2.188115,36.395701],[6.546112,37.329032],[10.409177,37.409177],[32.220277,31.534171],[32.351432,31.366935],[32.367263,31.321183],[32.326332,31.275712],[32.310771,31.256955],[32.306485,31.250784],[32.305175,31.245859],[32.304701,31.240173],[32.304078,31.22865],[32.30432,31.220009],[32.305401,31.193798],[32.30868,31.101482],[32.30884,31.096973],[32.313349,30.959484],[32.315801,30.881891],[32.316749,30.832008],[32.317177,30.818442],[32.317669,30.81143],[32.319202,30.805119],[32.326993,30.777533],[32.335298,30.748205],[32.338183,30.736395],[32.340812,30.72563],[32.342098,30.720024],[32.343728,30.712811],[32.344013,30.705045],[32.342476,30.69789],[32.339344,30.684428],[32.33286,30.65656],[32.326093,30.627388],[32.324259,30.620015],[32.322923,30.616423],[32.315078,30.602051],[32.311989,30.596237],[32.309886,30.591612],[32.308995,30.589652],[32.304839,30.580932],[32.303776,30.570936],[32.303946,30.565621],[32.305155,30.560251],[32.309042,30.549282],[32.312801,30.544911],[32.320118,30.535669],[32.328006,30.526559],[32.33423,30.518056],[32.336188,30.513515],[32.336788,30.512121],[32.33897,30.506124],[32.343769,30.484001],[32.345429,30.476297],[32.349985,30.452174],[32.357802,30.435216],[32.362452,30.41324],[32.365013,30.401903],[32.371307,30.364477],[32.372001,30.362383],[32.372923,30.360631],[32.37432,30.358856],[32.413348,30.314052],[32.442811,30.282656],[32.4683,30.273356],[32.487274,30.267524],[32.506479,30.261663],[32.528893,30.253179],[32.538655,30.242899],[32.55205,30.223001],[32.565398,30.200991],[32.567636,30.193881],[32.568511,30.186485],[32.568866,30.174391],[32.569061,30.165197],[32.569083,30.164319],[32.571572,30.065582],[32.573102,30.053687],[32.583382,29.999835],[32.585442,29.991212],[32.586504,29.984021],[32.587067,29.978722],[32.587502,29.972775],[32.586472,29.964744],[32.58411,29.957644],[32.580461,29.950635],[32.57586,29.943603],[32.571401,29.939105],[32.567231,29.935892],[32.56278,29.931928],[32.559968,29.92972],[32.553295,29.924821],[32.550781,29.920572],[32.546005,29.90946],[32.546005,29.903795],[32.554049,29.852356],[32.553995,29.847614],[32.534316,29.773183],[32.54236,29.63257],[32.544371,29.61334],[32.548393,29.592358],[32.599674,29.480381],[32.614756,29.454118],[32.630844,29.417339],[32.740534,29.181429],[32.820887,29.008613],[32.940536,28.751286],[33.033041,28.592489],[33.181886,28.374556],[33.31458,28.18027],[33.340722,28.15811],[33.36586,28.137718],[33.60102,27.943094],[33.655442,27.898053],[33.674193,27.88355],[33.703706,27.860724],[33.761019,27.809153],[33.815465,27.752737],[33.818462,27.749631],[33.837436,27.72997],[34.074325,27.532797],[34.102887,27.509024],[34.102887,27.509024],[42.75544,14.336583],[43.189582,13.344682],[43.189582,13.344682],[43.185256,13.313807],[43.188028,13.271231],[43.19972,13.234306],[43.340825,12.677617],[43.364873,12.629906],[43.380267,12.599365],[43.469014,12.507192],[43.691211,12.418707],[43.71623,12.408744],[44.142069,12.239163],[44.567907,12.069581],[44.993746,11.9],[45.080711,11.927235],[45.520055,12.064824],[45.9594,12.202414],[46.398745,12.340004],[46.838089,12.477593],[47.277434,12.615183],[47.716778,12.752772],[48.156123,12.890362],[48.595468,13.027952],[49.034812,13.165541],[49.474157,13.303131],[49.913501,13.440721],[50.352846,13.57831],[50.792191,13.7159],[51.231535,13.853489],[51.67088,13.991079],[52.110225,14.128669],[52.549569,14.266258],[52.988914,14.403848],[58.438634,15.679702],[58.438634,15.679702],[80.701832,5.701832],[93.468048,6.26668],[93.644801,6.27979],[94.095453,6.313216],[94.546105,6.346642],[94.996757,6.380069],[95.087901,6.386743],[95.538651,6.419749],[95.6777,6.381267],[96.113066,6.26078],[96.548433,6.140293],[96.983799,6.019807],[97.419165,5.89932],[97.854532,5.778833],[97.977656,5.62999],[98.265553,5.281954],[98.553451,4.933918],[98.841348,4.585882],[99.185654,4.304885],[99.535149,4.019653],[99.738417,3.85376],[99.932689,3.69521],[100.281985,3.410141],[100.63128,3.125072],[100.784531,3.0],[101.0,2.813011],[101.196657,2.711314],[101.448781,2.580933],[101.651348,2.420594],[102.003384,2.139419],[102.028193,2.119605],[102.250359,1.920972],[102.390329,1.853969],[102.79612,1.65972],[102.802769,1.656537],[102.950924,1.561332],[103.149876,1.425921],[103.343872,1.260979],[103.376343,1.233371],[103.465236,1.19105],[103.508891,1.172935],[103.575394,1.14584],[103.616935,1.133238],[103.678364,1.124421],[103.732268,1.127876],[103.788245,1.161041],[103.829739,1.182472],[103.862881,1.19766],[103.881411,1.205894],[103.931297,1.228061],[103.992803,1.250861],[104.055691,1.259842],[104.10683,1.26537],[104.121072,1.267352],[104.161425,1.27297],[104.208418,1.278497],[104.241756,1.284231],[104.272688,1.289551],[104.327282,1.297842],[104.449603,1.40631],[104.530497,1.551922],[104.749777,1.946632],[104.969057,2.341341],[105.078485,2.538313],[105.133782,2.987055],[105.151868,3.133821],[105.387157,3.519243],[105.509613,3.719836],[105.509613,3.719836],[109.625784,12.40235],[113.648011,21.648011]] ....
N.B. Unnecessary part at the data end is truncated.

VBA Code to Call API Returns XML instead of JSON

I am using an API. I have credentials. It returns XML instead of JSON.
Sub usbRequest()
Dim objRequest As MSXML2.XMLHTTP60
Dim strURL As String
Set objRequest = New MSXML2.XMLHTTP60
strURL = "https://someAPIURL.com/"
objRequest.Open "GET", strURL, True, "MyUserName", "MyPassword"
objRequest.setRequestHeader "Content-Type", "application/json"
objRequest.send
While objRequest.readyState <> 4
DoEvents
Wend
Debug.Print objRequest.responseText
End Sub
The API Documentation indicates that an Accept header specifying JSON should return JSON. I do have a reference set to Microsoft XML V 6.0.

VBA JSON POST Payload Issue

I'm trying to setup a API request to pull data from the Bureau of Labor Statistics. I succeeded in getting data using a get request, entering just the url and the series (as shown in the first code example). This works fine and I was able to parse out the JSON using Tim Hall's VBA-JSON converter and work with the data. My problem is that the get method returns only 3 years of data and I'd like to get more than that which requires a post method.
Sub GetCPItable()
Dim objhttp As Object
Dim strUrl As String
strUrl = "https://api.bls.gov/publicAPI/v1/timeseries/data/CUUR0000SA0"
Set objhttp = CreateObject("MSXML2.XMLHTTP")
With objhttp
.Open "get", strUrl, False
.Send
End With
MsgBox objhttp.ResponseText
End Sub
It seems (take this with a grain of salt, this is my first time working with api servers) like VBA is not passing my payload. I've checked my payload here and the JSON syntax appears correct and seems to be the correct syntax according to the page I first linked to. Yet the only things I recieve back from the api server is 404 not found errors. I've been trying different things to piece together what I'm missing all day from their source code examples (no VBA ofcourse) and posts here and elsewhere on the web and haven't made any progress. Here is a debugging version of the code that isn't working.
Sub GetCPItable()
Dim objhttp As Object
Dim body As String
'create our URL string and pass the user entered information to it
Dim strUrl As String
strUrl = "https://api.bls.gov/publicAPI/v1/timeseries/data"
Set objhttp = CreateObject("MSXML2.XMLHTTP")
With objhttp
.Open "POST", strUrl, False
.SetRequestHeader "Content-type", "application/json"
body = "{""seriesid"":""CUUR0000SA0""],""startyear"":""2008"",""endyear"":""2012""}"
.Send (body)
End With
MsgBox objhttp.ResponseText
End Sub
This is the error I get in response:
: responseText : "{
"status": "REQUEST_FAILED",
"responseTime": 0,
"message": [
"404 Error - Page Not Found"
],
"Results": [ ]
}" : String
Any help would be much appreciated. The only thing I can think to try next is using the V2 API but I'd like to avoid that if possible since it would require yearly reregistration.