Returning Null JSON Throwing Type Mismatch Error in VBA
Working with JSON files is much easier (IMHO) if you understand how the JsonConverter processes the JSON into a compound object. Let's look at a simple JSON format (taken from this useful site):
{
"array": [
1,
2,
3
],
"boolean": true,
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
The JsonConverter maps each of these data items into their VBA counterparts.
"array" maps to Collection (anytime you see the square brackets []) "boolean" maps to Boolean "null" maps to Null "number" maps to Double "object" maps to Dictionary (anytime you see the curly braces {}) "string" maps to String
So now we can do useful things with your JSON example, such as determine how many entires are in your "issues"
array by
Dim issues As Collection
Set issues = schema("issues")
Debug.Print issues.Count
Each of the entries in your "issues"
array is actually a compound object itself, so it's a Dictionary
. We could, therefore, do something like this:
Dim issue As Variant
For Each issue In issues
If issue.Exists("id") Then
Debug.Print "id = " & issue("id")
End If
Next issue
Of course, the "fields"
section of this single issue
is itself another Dictionary
. So stacking up the dictionary references we can do this too:
Debug.Print "field summary is " & issue("fields")("summary")
All of this is background, hopefully to make it easier on accessing members of a JSON structure. Your real question is on handling NULLs
. If the actual value of a field is set to null
(see the above sample), then you check it like so
If IsNull(issue("fields")("customfield_13500")) Then ...
A couple of other side notes before we put it all together:
- Always use
Option Explicit
- Avoid
Select
andActivate
- Always define and set references to all Workbooks and Sheets
In the example below, you'll see that I assumed you had to check each field for Null
. That is best accomplished by isolating that check in a subroutine rather than over-mess your code with a long string of If
statements. The advantage of the code example below is that you don't have to hard-code the number of issues because your logic can detect how many there are.
Option Explicit
Sub main()
Dim schema As Object
Set schema = GetJSON("C:\dev\junk.json")
Dim thisWB As Workbook
Dim destSH As Worksheet
Set thisWB = ThisWorkbook
Set destSH = thisWB.Sheets("Sheet1")
Dim anchor As Range
Set anchor = destSH.Range("A1")
Dim issues As Collection
Set issues = schema("issues")
Dim i As Long
Dim issue As Variant
For Each issue In issues
If issue.Exists("id") Then
SetCell anchor.Cells(1, 1), issue("fields")("issuetype")("name")
SetCell anchor.Cells(1, 2), issue("key")
SetCell anchor.Cells(1, 3), issue("fields")("summary")
'--- if you're not sure if the "name" field is there,
' then remember it's a Dictionary so check with Exists
If issue("fields")("status").Exists("name") Then
SetCell anchor.Cells(1, 4), issue("fields")("status")("name")
Else
SetCell anchor.Cells(1, 4), vbNullString
End If
SetCell anchor.Cells(1, 5), issue("fields")("assignee")
SetCell anchor.Cells(1, 6), issue("fields")("customfield_13301")
'--- possibly get the Count and iterate over the exact number of components
For i = 0 To issue("fields")("components").Count - 1
SetCell anchor.Cells(1, 7), issue("fields")("components")(i)("name")
Next i
SetCell anchor.Cells(1, 9), issue("fields")("customfield_13300")
SetCell anchor.Cells(1, 10), issue("fields")("customfield_10002")
Set anchor = anchor.Offset(1, 0)
End If
Next issue
End Sub
Function GetJSON(ByVal filename As String) As Object
'--- first ingest the JSON file and get it parsed
Dim fso As FileSystemObject
Dim jsonTS As TextStream
Dim jsonText As String
Set fso = New FileSystemObject
Set jsonTS = fso.OpenTextFile(filename, ForReading)
jsonText = jsonTS.ReadAll
Set GetJSON = JsonConverter.ParseJson(jsonText)
End Function
Private Sub SetCell(ByRef thisCell As Range, ByVal thisValue As Variant)
If IsNull(thisValue) Then
thisCell = vbNullString
Else
thisCell = thisValue
End If
End Sub