Search code examples
arraysjsonexcelvbatype-mismatch

JSON import generates run-time error '13' Type mismatch


I receive run-time error '13' Type mismatch when trying to import some data via IEX API using JSON.

I receive the error when setting the values for the cells in the For Each loop.

Here's a link to view the API data: https://api.iextrading.com/1.0/stock/aapl/financials?period=annual

Sub getFinancials()

'Write to ws
Dim ws As Worksheet
Set ws = Sheets("Financials")

Dim ticker As String
ticker = ws.Range("P7").value

Dim lastrow As Long
lastrow = ws.Cells(Rows.Count, "A").End(xlUp).Row

'Clear Range
ws.Range("A1:L" & lastrow).Clear

'Array Column Headers
Dim myarray As Variant
myarray = Array("reportDate", "grossProfit", "costOfRevenue", "operatingRevenue", "totalRevenue", "operatingIncome", "netIncome", "researchAndDevelopment", "operatingExpense", "currentAssets", "totalAssets", "totalLiabilities", "currentCash", "currentDebt", "totalCash", "totalDebt", "shareholderEquity", "cashChange", "cashFlow", "operatingGainsLosses")
Arrsize = UBound(myarray) - LBound(myarray) + 1

Dim rngTarget As Range
Set rngTarget = ws.Range(Cells(2, 1), Cells(Arrsize + 1, 1))
rngTarget.value = Application.Transpose(myarray)    

'Send web request for API Data
u = "https://api.iextrading.com/1.0/stock/" & ticker & "/financialsperiod=annual"
' https://api.iextrading.com/1.0/stock/aapl/financials?period=annual
Set myrequest = CreateObject("WinHttp.WinHttpRequest.5.1")
myrequest.Open "Get", u
myrequest.Send

'Parse JSON
Dim JSON As Object
Set JSON = JsonConverter.ParseJson(myrequest.ResponseText)

'Get # of Objects in Array
Dim arrayLen As Integer
arrayLen = JSON.Count

'Loop through Elements
Dim element As Variant
Dim x, y, r As Integer
r = 2
y = 2
x = 1

While x < arrayLen + 1
    For Each element In myarray
        ws.Cells(r, y).value = JSON(2)(element)
        y = y + 1
    Next element

    y = 2
    x = x + 1
    r = r + 1
Wend

End Sub

Solution

  • I just ran the JSON through the converter and this is the structure that I get:

    • -Dictionary(2 items)
    • --Collection(4 items)
    • ---Dictionary(20 items)

    You need to extract the data accordingly. Collections can be looped through with a simple for each loop. Dictionarys can be looped through with the following structure.

    Option Explicit
    
    
    Sub PrintFinancialReports()
    
        Dim apiURL As String
        apiURL = "https://api.iextrading.com/1.0/stock/aapl/financials?period=annual"
    
        Dim myrequest As WinHttpRequest
        Set myrequest = New WinHttpRequest
    
        myrequest.Open "Get", apiURL
        myrequest.Send
    
        Debug.Print myrequest.ResponseText ' print received JSON to check if it is valid
    
        Dim FinancialReportQuery As Dictionary
        Set FinancialReportQuery = JsonConverter.ParseJson(myrequest.ResponseText)
    
        Debug.Print FinancialReportQuery.Item("symbol")
    
        Dim Reports As Collection
        Set Reports = FinancialReportQuery.Item("financials")
    
        Dim report As Dictionary
        For Each report In Reports
            Dim reportContentKey As Variant '<-- variant is needed to loop a dictionary
            For Each reportContentKey In report
                Debug.Print reportContentKey, report.Item(reportContentKey)
            Next reportContentKey
        Next report
    
    End Sub
    

    Hope this helps