Since you only provided data for the 1st set of JSON format (the 2nd set of format looks weird anyway, are you sure that's correct?), below code only cater for the 1st set of JSON format:
Public Function ToJSON(rng As Range) As String
' Make sure there are two columns in the range
If rng.Columns.Count < 2 Then
ToJSON = CVErr(xlErrNA)
Exit Function
End If
Const rootKey As String = "sections"
Const surveyKey As String = "surveyQuestions"
Dim rngArr As Variant
rngArr = rng.Value2
Dim JSONStr As String
Dim JSONSurvey As String
Dim i As Long
' Skip the first row as it's been used as a header
For i = 2 To UBound(rngArr, 1)
If rngArr(i, 1) <> vbNullString Or rngArr(i, 2) <> vbNullString Then
If rngArr(i, 1) <> vbNullString Then
Dim currentName As String
If rngArr(i, 1) <> currentName Then
If currentName <> vbNullString Then
currentName = rngArr(i, 1)
JSONStr = JSONStr & JSONSurvey & "]},{" & KeyValue(rngArr(1, 1), rngArr(i, 1)) & "," & Chr(34) & surveyKey & Chr(34) & ": ["
JSONSurvey = vbNullString
Else
currentName = rngArr(i, 1)
JSONStr = JSONStr & "{" & KeyValue(rngArr(1, 1), rngArr(i, 1)) & "," & Chr(34) & surveyKey & Chr(34) & ": ["
End If
Else
End If
Else
JSONSurvey = JSONSurvey & ","
End If
Dim n As Long
For n = 2 To UBound(rngArr, 2)
If n = 2 Then JSONSurvey = JSONSurvey & "{"
Select Case n
Case 4, 5: JSONSurvey = JSONSurvey & KeyValue(rngArr(1, n), rngArr(i, n), False)
Case Else: JSONSurvey = JSONSurvey & KeyValue(rngArr(1, n), rngArr(i, n))
End Select
If n <> UBound(rngArr, 2) Then
JSONSurvey = JSONSurvey & ","
Else
JSONSurvey = JSONSurvey & "}"
End If
Next n
End If
Next
JSONStr = JSONStr & JSONSurvey & "]}"
' Strip out the last comma
JSONStr = Left(JSONStr, Len(JSONStr) - 1)
ToJSON = "{" & Chr(34) & rootKey & Chr(34) & ": [" & _
JSONStr & _
"}]}"
End Function
Private Function KeyValue(argKey As Variant, argValue As Variant, Optional ValueAsText As Boolean = True) As String
If ValueAsText Then
KeyValue = Chr(34) & argKey & Chr(34) & ":" & Chr(34) & argValue & Chr(34)
Else
KeyValue = Chr(34) & argKey & Chr(34) & ":" & LCase(argValue)
End If
End Function
Running this to Range("A1:G23") which is your entire data will produce this:
{"sections": [{"name":"About the inspection","surveyQuestions": [{"questionText":"report name","questionHelp":"some help 1","sortOrder":1,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"surveyor","questionHelp":"some help 2","sortOrder":2,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"asssigned to","questionHelp":"some help 3","sortOrder":3,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"client firstname","questionHelp":"some help 4","sortOrder":4,"isActive":true,"questionType":"NUMBER","options":""},{"questionText":"client lastname","questionHelp":"some help 5","sortOrder":5,"isActive":true,"questionType":"STARS","options":""},{"questionText":"report reference","questionHelp":"some help 6","sortOrder":6,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"date of inspection","questionHelp":"some help 7","sortOrder":7,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"house / building number","questionHelp":"some help 8","sortOrder":8,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"address line 1","questionHelp":"some help 9","sortOrder":9,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"address line 2","questionHelp":"some help 10","sortOrder":10,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"postcode","questionHelp":"some help 11","sortOrder":11,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"weather conditions","questionHelp":"some help 12","sortOrder":12,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"property status","questionHelp":"some help 13","sortOrder":13,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"property type","questionHelp":"property help","sortOrder":14,"isActive":true,"questionType":"LIST","options":"Bungalow;Semi-detatched, Detached, Terraced, Flat"}]},{"name":"Overall opinion","surveyQuestions": [{"questionText":"our overall opinion of the property","questionHelp":"some help 15","sortOrder":1,"isActive":true,"questionType":"TEXT","options":""}]},{"name":"About the property","surveyQuestions": [{"questionText":"type of property","questionHelp":"some help 17","sortOrder":1,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"approximate year property was built","questionHelp":"some help 18","sortOrder":2,"isActive":true,"questionType":"NUMBER","options":""},{"questionText":"approximate year the property was extended","questionHelp":"some help 19","sortOrder":3,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"approximate year the property was converted","questionHelp":"some help 20","sortOrder":4,"isActive":true,"questionType":"TEXT","options":""},{"questionText":"information relevant to flats and maisonettes","questionHelp":"some help 21","sortOrder":5,"isActive":true,"questionType":"TEXT","options":""}]}]}
And the pretty print version:
{
"sections": [
{
"name": "About the inspection",
"surveyQuestions": [
{
"questionText": "report name",
"questionHelp": "some help 1",
"sortOrder": 1,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "surveyor",
"questionHelp": "some help 2",
"sortOrder": 2,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "asssigned to",
"questionHelp": "some help 3",
"sortOrder": 3,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "client firstname",
"questionHelp": "some help 4",
"sortOrder": 4,
"isActive": true,
"questionType": "NUMBER",
"options": ""
},
{
"questionText": "client lastname",
"questionHelp": "some help 5",
"sortOrder": 5,
"isActive": true,
"questionType": "STARS",
"options": ""
},
{
"questionText": "report reference",
"questionHelp": "some help 6",
"sortOrder": 6,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "date of inspection",
"questionHelp": "some help 7",
"sortOrder": 7,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "house / building number",
"questionHelp": "some help 8",
"sortOrder": 8,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "address line 1",
"questionHelp": "some help 9",
"sortOrder": 9,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "address line 2",
"questionHelp": "some help 10",
"sortOrder": 10,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "postcode",
"questionHelp": "some help 11",
"sortOrder": 11,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "weather conditions",
"questionHelp": "some help 12",
"sortOrder": 12,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "property status",
"questionHelp": "some help 13",
"sortOrder": 13,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "property type",
"questionHelp": "property help",
"sortOrder": 14,
"isActive": true,
"questionType": "LIST",
"options": "Bungalow;Semi-detatched, Detached, Terraced, Flat"
}
]
},
{
"name": "Overall opinion",
"surveyQuestions": [
{
"questionText": "our overall opinion of the property",
"questionHelp": "some help 15",
"sortOrder": 1,
"isActive": true,
"questionType": "TEXT",
"options": ""
}
]
},
{
"name": "About the property",
"surveyQuestions": [
{
"questionText": "type of property",
"questionHelp": "some help 17",
"sortOrder": 1,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "approximate year property was built",
"questionHelp": "some help 18",
"sortOrder": 2,
"isActive": true,
"questionType": "NUMBER",
"options": ""
},
{
"questionText": "approximate year the property was extended",
"questionHelp": "some help 19",
"sortOrder": 3,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "approximate year the property was converted",
"questionHelp": "some help 20",
"sortOrder": 4,
"isActive": true,
"questionType": "TEXT",
"options": ""
},
{
"questionText": "information relevant to flats and maisonettes",
"questionHelp": "some help 21",
"sortOrder": 5,
"isActive": true,
"questionType": "TEXT",
"options": ""
}
]
}
]
}
Disclaimer: the code looks messy but it's late and it works!