I am very new to Excel macro and need help with the below.
I have a nested json string as below.
{
"Version": 1,
"Date": "2023-09-22",
"Adjustment": 19,
"stock": {
"Rate": 1.41,
"Price": 19
},
"units": [
{
"Place": "NW",
"unitId": 2,
"depart": [1, 2],
"Usage": [
{
"fuel": "gas",
"Rate": 19
},
{
"fuel": "diesel",
"Rate": 19
}
],
"ip": [
{
"fuel": "gas",
"aCoef": 19
},
{
"fuel": "diesel",
"aCoef": 2
}
]
},
{
"Place": "London",
"unitId": 2,
"depart": [1, 2],
"Usage": [
{
"fuel": "liquid",
"Rate": 19
}
],
"Price": {
"Rate1": 19,
"Rate2": 19
}
}
]
}
I have flattened it as below in the excel.
whenever I update any row in the value column in excel I need a new json in column E with the updated value .
For Instance when I update adjustment value as 45 in the excel sheet,when I run a marco I want VBA code to generate a new json with the updated value as 45 for adjustment.Please provide inputs.
Thank you.
Code used
Sub UpdateJSON()
Dim ws As Worksheet
Dim lastRow As Long
Dim cell As Range
Dim key As String
Dim value As String
Dim jsonStr As String
' Set the worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
' Find the last row with data
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' Initialize JSON string
jsonStr = "{"
' Iterate over each row to build the JSON structure
For Each cell In ws.Range("A2:A" & lastRow)
key = Trim(cell.Value)
value = Trim(cell.Offset(0, 1).Value)
jsonStr = jsonStr & BuildJSONString(key, value) & ","
Next cell
' Remove trailing comma and close JSON string
If Right(jsonStr, 1) = "," Then
jsonStr = Left(jsonStr, Len(jsonStr) - 1)
End If
jsonStr = jsonStr & "}"
' Output the JSON string to the specified cell
ws.Cells(1, 8).Value = jsonStr ' H1 corresponds to column 8
End Sub
Function BuildJSONString(key As String, value As String) As String
Dim jsonSegment As String
Dim keys As Variant
Dim i As Integer
Dim tempKey As String
keys = Split(key, ".")
' Construct the JSON key path
jsonSegment = ""
For i = LBound(keys) To UBound(keys)
tempKey = keys(i)
' Check if the key contains an array index
If InStr(tempKey, "[") > 0 And InStr(tempKey, "]") > 0 Then
tempKey = Replace(tempKey, "[", ":[")
End If
jsonSegment = jsonSegment & """" & tempKey & """:"
Next i
' Add the value to the JSON key path
If IsNumeric(value) Then
jsonSegment = jsonSegment & value
ElseIf Left(value, 1) = "[" And Right(value, 1) = "]" Then
jsonSegment = jsonSegment & value
Else
jsonSegment = jsonSegment & """" & value & """"
End If
BuildJSONString = jsonSegment
End Function
Result obtained
{"inputVersion":3,"CVersion":0,"Adjustment":1222,"stock":"Rate":1.41,"stock":"Price":222,"units:[0]":"Place":"NW","units:[0]":"unitId":2,"units:[0]":"depart":[1, 2],"units:[0]":"usage:[0]":"fuel":"gas","units:[0]":"usage:[0]":"Rate":24,"units:[0]":"usage:[1]":"fuel":"Disel","units:[0]":"usage:[1]":"Rate":222,"units:[0]":"ip:[0]":"fuel":"gas","units:[0]":"ip:[0]":"aCoef":222,"units:[0]":"ip:[1]":"fuel":"disel","units:[0]":"ip:[1]":"aCoef":222,"units:[1]":"Name":"London","units:[1]":"unitId":2,"units:[1]":"depart":[1, 2],"units:[1]":"usage:[0]":"fuel":"liquid","units:[1]":"usage:[0]":"rate":99222,"units:[1]":"Price":"rate1":1222,"units:[1]":"Price":"rate2":16222}
But the expected json format is different in the above result.
2
Answers
Parsing JSON is more difficult and complex than you might have expected. Parsing nested JSON is even more complicated.
VBA-JSON is an excellent free tool for parsing JSON.
The code has been tested with your sample data, but there may be opportunities for further improvement.
Note:
Please include a reference to
Microsoft Scripting Runtime
before run the code.Output:
Slightly different approach also using VBA-JSON:
Output: