You should check if a node exists, looking at the (converted) XML you can see that availableToBack and availabletoLay do not always exist.
There's only 1 availableToLay under "Kent v Essex", and t availableToBack:
<eventNodes>
<eventId>29417978</eventId>
<event>
<eventName>Kent v Essex</eventName>
<countryCode>GB</countryCode>
<timezone>GMT</timezone>
<openDate>2019-08-18T10:00:00Z</openDate>
</event>
<marketNodes>
<marketId>1.161362186</marketId>
<isMarketDataDelayed>true</isMarketDataDelayed>
<state>
<betDelay>0</betDelay>
<bspReconciled>false</bspReconciled>
<complete>true</complete>
<inplay>false</inplay>
<numberOfWinners>1</numberOfWinners>
<numberOfRunners>3</numberOfRunners>
<numberOfActiveRunners>3</numberOfActiveRunners>
<totalMatched>0</totalMatched>
<totalAvailable>14844.762771507034</totalAvailable>
<crossMatching>true</crossMatching>
<runnersVoidable>false</runnersVoidable>
<version>2893531625</version>
<status>OPEN</status>
</state>
<runners>
<selectionId>5901</selectionId>
<handicap>0</handicap>
<description>
<runnerName>Kent</runnerName>
</description>
<state>
<sortPriority>1</sortPriority>
<totalMatched>0</totalMatched>
<status>ACTIVE</status>
</state>
<exchange>
<availableToBack>
<price>1.42</price>
<size>56.84</size>
</availableToBack>
<availableToBack>
<price>1.1</price>
<size>13.6</size>
</availableToBack>
<availableToLay>
<price>100</price>
<size>8.51</size>
</availableToLay>
</exchange>
</runners>
This can be done like this:
(please note, I do not do this kind of stuff in Excel very often, so there might be 'smarter' way to do this ... )
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://www.betfair.com/www/sports/exchange/readonly/v1/bymarket?_ak=nzIFcwyWhrlwYMrh&alt=json¤cyCode=USD&locale=en&marketIds=1.161189078,1.161073119,1.161362337,1.161362195,1.161362198,1.161362200,1.161362186,1.161362202,1.161362187,1.161362205,1.161362188,1.161362189,1.161425408&rollupLimit=25&rollupModel=STAKE&types=MARKET_STATE,%20EVENT,RUNNER_DESCRIPTION,RUNNER_STATE,RUNNER_EXCHANGE_PRICES_BEST", False
.send
s = .responseText
Set json = JsonConverter.ParseJson(s)
End With
Dim runners As Object, runner As Object, results(), r As Variant
Set runners = json("eventTypes")(1)("eventNodes")
Dim obj0 As Object
ReDim results(1 To runners.Count, 1 To 7)
intEventNode = 1
For Each eventNode In runners
r = r + 1
Name = eventNode("event")("eventName")
If eventNode.Exists("marketNodes") Then
intMarketNode = 1
For Each marketNode In json("eventTypes")(1)("eventNodes")(intEventNode)("marketNodes")
If marketNode.Exists("runners") Then
intRunner = 1
For Each runner In json("eventTypes")(1)("eventNodes")(intEventNode)("marketNodes")(intMarketNode)("runners")
If runner.Exists("exchange") Then
runnerName = runner("description")("runnerName")
For Each ex In json("eventTypes")(1)("eventNodes")(intEventNode)("marketNodes")(intMarketNode)("runners")(intRunner)("exchange")("availableToBack")
If ex.Exists("price") Then
'MsgBox "name: " + Name + Chr$(13) + "runnerName: " + runnerName + Chr$(13) + "availableToBack: " + CStr(ex("price"))
Cells(r, 1) = Name
Cells(r, 2) = runnerName
Cells(r, 3) = "availableToBack"
Cells(r, 4) = ex("price")
Cells(r, 5) = ex("size")
r = r + 1
End If
Next
For Each ex In json("eventTypes")(1)("eventNodes")(intEventNode)("marketNodes")(intMarketNode)("runners")(intRunner)("exchange")("availableToLay")
If ex.Exists("price") Then
'MsgBox "name: " + Name + Chr$(13) + "runnerName: " + runnerName + Chr$(13) + "availableToLay: " + CStr(ex("price"))
Cells(r, 1) = Name
Cells(r, 2) = runnerName
Cells(r, 3) = "availableToLay"
Cells(r, 4) = ex("price")
Cells(r, 5) = ex("size")
r = r + 1
End If
Next
End If
intRunner = intRunner + 1
Next
End If
intMarketNode = intMarketNode + 1
Next
intEventNode = intEventNode + 1
End If
Next