Building a JSON Request Body in VBA (1 Viewer)

yellenick

New member
Local time
Today, 11:15
Joined
Apr 11, 2023
Messages
4
I am trying to call an API. To do so I need to construct a JSON request body.

What is the best way to do this? Is there a library I can use to prevent using "& _" on every line?
 
I tend to use the format of

strSQL = strSQL & "......."

when building sql strings and not continuation characters.
 
Where is the data for the body coming from? Can you use a loop?
 
Where is the data for the body coming from? Can you use a loop?
It's the UPS standard request for getting shipping rates, looks like this:

{
"RateRequest": {
"Request": {
"RequestOption": "Rate",
"TransactionReference": {
"CustomerContext": "CustomerContext",
"TransactionIdentifier": "TransactionIdentifier"
}
},
"Shipment": {
"Shipper": {
"Name": "ShipperName",
"ShipperNumber": "XXXXX",
"Address": {
"AddressLine": "",
"City": "TIMONIUM",
"StateProvinceCode": "MD",
"PostalCode": "21093",
"CountryCode": "US"
}
},
"ShipTo": {
"Name": "ShipToName",
"Address": {
"AddressLine": "",
"City": "Alpharetta",
"StateProvinceCode": "GA",
"PostalCode": "30005",
"CountryCode": "US"
}
},
"ShipFrom": {
"Name": "ShipFromName",
"Address": {
"AddressLine": "",
"City": "TIMONIUM",
"StateProvinceCode": "MD",
"PostalCode": "21093",
"CountryCode": "US"
}
},
"PaymentDetails": {
"ShipmentCharge": {
"Type": "01",
"BillShipper": {
"AccountNumber": "XXXXX"
}
}
},
"Service": {
"Code": "03",
"Description": "Ground"
},
"Package": [
{
"PackagingType": {
"Code": "02"
},
"Dimensions": {
"UnitOfMeasurement": {
"Code": "IN",
"Description": "Inches"
},
"Length": "9",
"Width": "6",
"Height": "5"
},
"PackageWeight": {
"UnitOfMeasurement": {
"Code": "LBS",
"Description": "Pounds"
},
"Weight": "1"
}
}
]
}
}
}
 
With the library I linked, getting the City from ShipFrom would be like this:
Code:
    Dim ShipFromCity As String
    Dim json As Object
    Set json = ParseJson(myJsonString)
    
    ShipFromCity= json("RateRequest")("Shipment")("ShipFrom")("Address")("City")
 
With the library I linked, getting the City from ShipFrom would be like this:
Code:
    Dim ShipFromCity As String
    Dim json As Object
    Set json = ParseJson(myJsonString)
   
    ShipFromCity= json("RateRequest")("Shipment")("ShipFrom")("Address")("City")

Thank you, but I have not gotten to the parsing of the JSON yet, I am building the request body to send to the API. I would like to build the request body without having to append & _ to each line of the string.

Any ideas?
 
Yes, just put it in a dictionary then use the ConvertToJson function of the library. I have a procedure here, I removed some things, but you can get the idea, I hope.

This is how you could send the dictionary.
Code:
Public Sub AddProduct(myProduct As Dictionary)
    Set oRequest = CreateObject("MSXML2.ServerXMLHTTP.3.0")
    With oRequest
        .Open "POST", baseURL & "someUrl"
        .Send ConvertToJson(myProduct, 4)
        strResponse = .responseText
    End With
End Sub

And this is how you could build the dictionary.
Rich (BB code):
Private Sub btnSubmit_Click()
  
    Dim myProduct As Dictionary: Set myProduct = New Dictionary
    myProduct.Add "ProductDescription", Me.txtProductDescription.Value
    myProduct.Add "Unit", Me.txtUnit.Value
    myProduct.Add "Price", Me.txtPrice.Value
  
    If Me.OpenArgs = "Add" Then
        AddProduct myProduct
    ElseIf Not IsNull(Me.OpenArgs) Then
        EditProduct myProduct, Me.OpenArgs
    End If
    GetProducts
    Forms!frmProducts.Form!frmProductsList.Requery
    DoCmd.Close
End Sub
 
It depends on the endpoint requirements, though. Some of them may require you to do something like this:
Code:
.SetRequestHeader "Authorization", "Bearer " & MyApiKey
.SetRequestHeader "Content-Type", "application/json; charset=UTF-8"
.Send myDictionary
 
You could also look at my JSON app which will do almost all of the work for you.

 
I would like to build the request body without having to append & _ to each line of the string.
I would use the json parser.

Still, a few alternatives:
1)
Code:
s = s & "..."
s = s & """ShipTo"": {"
s = s & """Name"": """ & Data("ShipToName") & ""","
s = s & """Address"": {"
s = s & """AddressLine"": """","
s = s & """City"": """ & Data("ShipToCity") & ""","
s = s & "..."

2)
Code:
With New StringCollection
   .Add "..."
   .Add """ShipTo"": {"
   .Add """Name"": """ & Data("ShipToName") & ""","
   .Add """Address"": {"
   .Add """AddressLine"": """","
   .Add """City"": """ & Data("ShipToCity") & ""","
   .Add "..."

   JsonString = .ToString("")
End With

3a)
Code:
Const JsonTemplate As String = "..." & _
   """ShipTo"": {" & _
   """Name"": ""{%ShipToName%}""," & _
   """Address"": {" & _
   """AddressLine"": """"," & _
   """City"": ""{%ShipToCity%}""," & _
   "..."

JsonString = JsonTemplate

For Each DataItem In Data
   JsonString = Replace(JsonString, "{%" & DataItem.Name & "%}", DataItem.Value)
Next

3b)
Code:
JsonString = DLookup("TemplateString", "JsonTemplates", "Id='UPS standard request'")
For Each DataItem In Data
   JsonString = Replace(JsonString, "{%" & DataItem.Name & "%}", DataItem.Value)
Next
 
Last edited:
I would like to build the request body without having to append & _ to each line of the string.
You could type the format into a long text field that is saved to a table. Include placeholders for each piece of data. Then you would read the data and use a list of Replace() functions to replace the placeholders with each value. Then pass the string to the API.
 

Users who are viewing this thread

Back
Top Bottom