2

I am trying to parse the JSON data from a website. I successfully get the JSON string, but I can't parse it. An exception is thrown in the code below:

Runtime Error 424. Object Required

This is my code:

' Download string from URL
Public Function DownloadDataFromURL(url As String) As String
    Set Myrequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    Myrequest.Open "GET", url
    Myrequest.send
    Dim WebResponse As String
    WebResponse = Myrequest.responseText
    Cells(1, 1).Value = WebResponse
    DownloadDataFromURL = WebResponse
End Function

' Download all cryptocoins in
Public Sub LoadCryptocoins()
    Dim Path As String
    Dim Data As String
    Dim json As Object

    Path = "https://api.coinmarketcap.com/v1/ticker/"
    Data = DownloadDataFromURL(Path)

    Set jp = New JsonParser
    Set jo = jp.Decode(Data)

    For Each Item In jp.EnumKeys(jo)
        MsgBox (Item.GetValue(jo, "id")) 'The exception is thrown here
    Next
End Sub

I'm using the JSON Parser from here: Parsing JSON in Excel VBA

The raw JSON data I a processing can be found here: https://api.coinmarketcap.com/v1/ticker/

How can I get every coin name and the price in USD?

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
n00b.exe
  • 287
  • 1
  • 3
  • 12
  • 1
    *I can't parse it*, why? Are you getting an error? Describe what's happening. – Racil Hilan Jan 03 '18 at 20:26
  • 1
    https://github.com/VBA-tools/VBA-JSON is the tool most frequently recommended here for parsing JSON in VBA. Your JSON object in this case is an array though, so you can't enumerate its "keys" – Tim Williams Jan 03 '18 at 20:29
  • @RacilHilan Runtime error 424 object required is the error I get – n00b.exe Jan 03 '18 at 20:48
  • 1
    You need to edit your question and add the error there, not in a comment. And also mention which line you're getting the error at. – Racil Hilan Jan 03 '18 at 20:50
  • @RacilHilan I edited my post. Any idea ? – n00b.exe Jan 03 '18 at 21:56
  • The problem is that you said *I'm using the JSON Parser from here* and then you linked to another question on SO. I don't know what parser you're using. I followed that link and it even linked to another question, which in turns had two links. I tried the first one [vba-json](https://code.google.com/archive/p/vba-json/) and both the download and wiki pages are down, so I cannot download it to test, and cannot check the docs. Provide the correct link to the parser that you're using. – Racil Hilan Jan 04 '18 at 02:11
  • Possible duplicate of [Parsing JSON in Excel VBA](https://stackoverflow.com/questions/6627652/parsing-json-in-excel-vba) – Liam Jul 09 '18 at 16:05

4 Answers4

3

Since Excel 2010 version you can download the add-in "Power Query" or if you have 2016 version it comes by default in Excel as "Get & Transform". you can extract data easily, in your case it will be:

  1. Go Data
  2. Select "From Web"

  1. Add the JSON url

It will open the ETL excel tools (Query Editor):

  1. Go "Transform"

  2. Select "To Table"

  3. I didn't change any parameter > OK

7.Click in the corner with two arrows and select the fields what you want.

  1. There is a lot of tools to play with the data. Then Go "Home" and select "close and load" it will create a new sheet with your data.

This is the "advance editor" code if you want just to copy and paste:

let
    Source = Json.Document(Web.Contents("https://api.coinmarketcap.com/v1/ticker/")),
    #"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"id", "name", "symbol", "rank", "price_usd", "price_btc", "24h_volume_usd", "market_cap_usd", "available_supply", "total_supply", "max_supply", "percent_change_1h", "percent_change_24h", "percent_change_7d", "last_updated"}, {"Column1.id", "Column1.name", "Column1.symbol", "Column1.rank", "Column1.price_usd", "Column1.price_btc", "Column1.24h_volume_usd", "Column1.market_cap_usd", "Column1.available_supply", "Column1.total_supply", "Column1.max_supply", "Column1.percent_change_1h", "Column1.percent_change_24h", "Column1.percent_change_7d", "Column1.last_updated"})
in
    #"Expanded Column1"
virtualdvid
  • 2,323
  • 3
  • 14
  • 32
3

Try the below script. It will fetch you all the data you have mentioned. No external parser is required to achieve this:

Sub coinmarketcap_data()
    Dim http As New XMLHTTP60, res As Variant

    With http
        .Open "GET", "https://api.coinmarketcap.com/v1/ticker/", False
        .send
        res = .responseText
    End With

    For r = 1 To UBound(Split(res, "id"": """))
        Cells(r, 1) = Split(Split(Split(res, "name"": """)(r), """symbol")(0), """")(0)
        Cells(r, 2) = Split(Split(Split(res, "price_usd"": """)(r), """price_btc")(0), """")(0)
    Next r
End Sub

Reference to add to the library:

Microsoft XML, v6.0
SIM
  • 21,997
  • 5
  • 37
  • 109
  • Thanks, yur solution works, but is there also a way to use the json parser I linked? I think using the parser might be more reliable, especially if some of the attributes change, the splitting method might not work anymore. – n00b.exe Jan 03 '18 at 21:52
  • I'm not a great fan of `vba-json parser`, so I'm sorry that I can't help you on that. – SIM Jan 03 '18 at 21:59
1

The exception that you get is because your parsed JSON object jo is a collection, so you have to loop through the collection items first before you can access each item's keys and values.

I don't know what parser you're using, so I will answer using VBA-JSON:

Public Sub LoadCryptocoins()
    Dim Path As String
    Dim Data As String
    Dim json As Object

    Path = "https://api.coinmarketcap.com/v1/ticker/"
    Data = DownloadDataFromURL(Path)

    Set json = JsonConverter.ParseJson(Data)
    For Each Item In json
        MsgBox (Item("name") & " $" & Item("price_usd"))
    Next
End Sub

Now, using your parser, I imagine it should be something like this:

Public Sub LoadCryptocoins()
    Dim Path As String
    Dim Data As String
    Dim json As Object

    Path = "https://api.coinmarketcap.com/v1/ticker/"
    Data = DownloadDataFromURL(Path)

    Set jp = New JsonParser
    Set jo = jp.Decode(Data)

    For Each Item In jo
        MsgBox (Item.GetValue(jo, "name") & " $" & Item.GetValue(jo, "price_usd"))
    Next
End Sub

But this is a complete blind shot in the dark. Once you post a link to the parser that you're using, I can update my answer.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
0

Simple example using https://github.com/VBA-tools/VBA-JSON

Public Sub LoadCryptocoins()

    Dim Path As String
    Dim Data As String
    Dim jo As Object, o
    Dim i As Long

    Path = "https://api.coinmarketcap.com/v1/ticker/"
    Data = DownloadDataFromURL(Path)

    Set jo = json.parse(Data)

    For i = 1 To jo.Count
        Set o = jo(i)
        Debug.Print o("id")
    Next i

End Sub

The return value from json.parse will be a Collection if the JSON response represents an array, or a Scripting Dictionary if it's an object.

Tim Williams
  • 154,628
  • 8
  • 97
  • 125