Building a JSON Request Body in VBA (1 Viewer)

yellenick

New member
Local time
Today, 03:25
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?
 

Gasman

Enthusiastic Amateur
Local time
Today, 08:25
Joined
Sep 21, 2011
Messages
14,299
I tend to use the format of

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

when building sql strings and not continuation characters.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 00:25
Joined
Oct 29, 2018
Messages
21,473
Where is the data for the body coming from? Can you use a loop?
 

yellenick

New member
Local time
Today, 03:25
Joined
Apr 11, 2023
Messages
4
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"
}
}
]
}
}
}
 

561414

Active member
Local time
Today, 02:25
Joined
May 28, 2021
Messages
280
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")
 

yellenick

New member
Local time
Today, 03:25
Joined
Apr 11, 2023
Messages
4
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?
 

561414

Active member
Local time
Today, 02:25
Joined
May 28, 2021
Messages
280
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
 

561414

Active member
Local time
Today, 02:25
Joined
May 28, 2021
Messages
280
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
 

isladogs

MVP / VIP
Local time
Today, 08:25
Joined
Jan 14, 2017
Messages
18,221
You could also look at my JSON app which will do almost all of the work for you.

 

Josef P.

Well-known member
Local time
Today, 09:25
Joined
Feb 2, 2023
Messages
826
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:

Pat Hartman

Super Moderator
Staff member
Local time
Today, 03:25
Joined
Feb 19, 2002
Messages
43,275
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

Top Bottom