Excel VBA JSON POST Loop - json

What i'm trying to accomplish is to go through a specific Table Column and for each visible row return the value of that cell. This cell contains a formula that creates a JSON from values in the table in other columns. Here's an example of the column i want to loop through:
Json Output
Inside this loop i'm going to use each cell value and POST the JSON, but it needs to loop through and post for each cell in that columnn. Here is the VBA code I'm using to POST a single cell without the loop:
Sub FulcrumUpload()
Dim xhr As Object, thisRequest As String, JSONvalue As String
Set xhr = CreateObject("Microsoft.XMLHTTP")
thisRequest = "https://api.fulcrumapp.com/api/v2/records.json"
xhr.Open "POST", thisRequest, False
xhr.setRequestHeader "Accept", "application/json"
xhr.setRequestHeader "Content-type", "application/json"
xhr.setRequestHeader "X-ApiToken", "11111111111111"
xhr.Send Sheets("Fulcrum Upload").Range("V3").value
End Sub

Assuming your filtered data is in column V, from V3 onwards, perhaps something like:
Public Sub FulcrumUpload()
Dim xhr As Object, thisRequest As String, rng As Range
Set xhr = CreateObject("Microsoft.XMLHTTP")
thisRequest = "https://api.fulcrumapp.com/api/v2/records.json"
With ThisWorkbook.Worksheets("Fulcrum Upload")
For Each rng In .Range("V3:V" & .Cells(.Rows.Count, "V").End(xlUp).Row).SpecialCells(xlVisible)
If Not IsEmpty(rng) Then
With xhr
.Open "POST", thisRequest, False
.setRequestHeader "Accept", "application/json"
.setRequestHeader "Content-type", "application/json"
.setRequestHeader "X-ApiToken", "11111111111111"
.send rng.Value
End With
End If
Next
End With
End Sub

Related

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

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.

Getting a JSON response from a REST API with VBA

Am trying to retrieve data as JSON with the following code, but am just getting an XML response:
Public Sub vbajson()
Dim http As Object
Dim sht As Worksheet
Dim authKey As String
Dim accNr As String
Set sht = Worksheets("Account")
authKey = "abc"
accNr = "123"
Set http = CreateObject("MSXML2.XMLHTTP")
With http
.Open "GET", "https://api.tradier.com/v1/accounts/" & accNr & "/balances", False
.setRequestHeader "Content-type", "application/json"
.setRequestHeader "Accept", "application/json"
.setRequestHeader "Authorization", "Bearer " & authKey
.Send
End With
MsgBox http.responsetext
End Sub
msgbox output:
instead of using
.Open "GET", "https://api.tradier.com/v1/accounts/" & accNr & "/balances", False
I tested the following link, leaving the rest of the VBA code unchanged:
.Open "GET", "http://jsonplaceholder.typicode.com/users", False`
and get the following result, which is the data structure I want:
Am also getting data in JSON structure using the following Python code (code borrowed from here: https://documentation.tradier.com/brokerage-api/accounts/get-account-balance)
import requests
response = requests.get('https://api.tradier.com/v1/accounts/123/positions',
params={},
headers={'Authorization': 'Bearer abc', 'Accept': 'application/json'}
)
json_response = response.json()
print(response.status_code)
print(json_response)
Any idea how I need to update my VBA code to get the data in JSON structure? What is the issue?
I want to get JSON, as xml will no longer be supported once the API gets updated.

VBA to parse data from web API

Public Sub IMPORTMESTER()
Dim xTOK As String
Dim URL As String
Dim httpREQ As Object
Dim JSON As Object
Dim xLINE As Variant
xTOK = "bdj62bzknriy3dd9g561on2xl2"
URL = "https://api.smartsheet.com/2.0/sheets/7352150637471620"
Set httpREQ = CreateObject("MSXML2.XMLHTTP.6.0")
With httpREQ
.Open "GET", URL, False
.setRequestHeader "Authorization", "Bearer " & xTOK
.setRequestHeader "Content-Type", "application/json"
.Send
End With
xLINE = httpREQ.ResponseText
MsgBox ("Complete!")
End Sub
So, Ive returned data I need, but I tried several methods to parse it and paste in excel, but without success. Here is the part of responsetext:
"cells":[{"columnId":2400415921792900,"value":"MWP08","displayValue":"MWP08"},{"columnId":6904015549163396,"value":"A-WP-80301D5D10C00","displayValue":"A-WP-80301D5D10C00"},{"columnId":1274516014950276,"value":"MWP0830W27V50KD","displayValue":"MWP0830W27V50KD"},{"columnId":5778115642320772,"value":"WP08 30W,120-277VAC,Ra70 5000K Clear lens,Dark bronze","displayValue":"WP08 30W,120-277VAC,Ra70 5000K Clear lens,Dark bronze"},{"columnId":3526315828635524,"value":"image002.png","displayValue":"image002.png","formula":"=SYS_CELLIMAGE(\"image002.png\",\"vDOY-InMRamvhitNGotKzb\",35,52,\"image.png\")","image":{"id":"vDOY-InMRamvhitNGotKzb","height":35,"width":52,"altText":"image002.png"}},{"columnId":8029915456006020},{"columnId":711566061528964,"value":1884.0,"displayValue":"1884","linkInFromCell":{"status":"INACCESSIBLE","sheetId":4533800614029188,"rowId":null,"columnId":null,"sheetName":"MLC-Inventory扣减(2019)"}},{"columnId":2963365875214212,"value":"https://mesterleds.com/wp-content/uploads/2017/12/WP01-45W70W.png","displayValue":"https://mesterleds.com/wp-content/uploads/2017/12/WP01-45W70W.png"},{"columnId":7466965502584708},{"columnId":1837465968371588},{"columnId":6341065595742084},{"columnId":4089265782056836},{"columnId":8592865409427332},{"columnId":430091084818308,"value":175.0,"displayValue":"175"},{"columnId":4933690712188804},{"columnId":2681890898503556},{"columnId":7185490525874052},{"columnId":1555990991660932},{"columnId":6059590619031428}]},{"id":7080298036914052,"rowNumber":3,"siblingId":2576698409543556,"expanded":true,"createdAt":"2019-01-31T00:06:35Z","modifiedAt":"2019-02-18T16:56:50Z",
Each row of table I need starts with:"cells';[{" while I only need "displayValue": for columns!
I tried several solutions and suggestions from various threads from StackOverflow but... no luck!
Below is desired output:
Final excel format (unneccessary columns hidden)
If only after displayValue you can use the following with jsonconverter.bas. You add the .bas to your project and then VBE > Tools > References> Add a reference to Microsoft Scripting Runtime.
Option Explicit
Public Sub IMPORTMESTER()
Dim xTOK As String
Dim URL As String
Dim httpREQ As Object
Dim json As Object
Dim xLINE As Variant
xTOK = "token"
URL = "https://api.smartsheet.com/2.0/sheets/7352150637471620"
Set httpREQ = CreateObject("MSXML2.XMLHTTP.6.0")
With httpREQ
.Open "GET", URL, False
.setRequestHeader "Authorization", "Bearer " & xTOK
.setRequestHeader "Content-Type", "application/json"
.send
End With
xLINE = httpREQ.responseText
Set json = JsonConverter.ParseJson(xLINE)("rows")
Dim item As Object, nextitem As Object, i As Long
For Each item In json
For Each nextitem In item("cells")
i = i + 1
ActiveSheet.Cells(i, 1) = nextitem("displayValue")
Next
Next
End Sub
The item you want is nested within the json where {} is a dictionary, and [] is a collection.

VBA Parse String Response From API

I'm getting below type of responses from an API:
"{"success":false,"error":"Incorrect apikey"}"
"{"success":true,"error":"Correct apikey"}"
In VBA, how to know if response is true or false ?
My current code is below and am getting response in hReq.ResponseText and it is not always fixed (more keys can be added to json). Although the part below is fixed and I have to get only if it returning true or false.
"{"success":false
Code:
Dim hReq As Object
Dim strUrl As String
strUrl = "https://myWebAPI/myMethod?apikey=123456"
Set hReq = CreateObject("MSXML2.XMLHTTP")
With hReq
.Open "GET", strUrl, False
.Send
End With
MsgBox hReq.ResponseText
I know this is basic question but sorry am new to VBA.
Purely based on what you have shown you can get True/False with
Split(Split(hReq.ResponseText, ":")(1), ",")(0)