0

I'm parsing a JSON string similar to the solution at this link: Parse JSON with VBA (Access 2010). However, I'm getting the "subscript out of range" error.

Public Sub GetValues()
    Dim s As String, rates(), i As Long
    s = "{""id"":""14acfa60-c0e1-47fb-8f80-ca0831bf3b52"",""class"":""us_equity"",""exchange"":""ARCA"",""symbol"":""UVXY"",""name"":"""",""status"":""active"",""tradable"":true,""marginable"":true,""shortable"":false,""easy_to_borrow"":false}"
    rates = Array("id", "class", "exchange", "symbol", "name", "status", "tradeable", "marginable", "shortable", "easy_to_borrow")

    For i = LBound(rates) To UBound(rates)
        Debug.Print rates(i) & ":" & GetRate(s, rates(i))
    Next i
End Sub
Public Function GetRate(ByVal s As String, ByVal delimiter As String) As String
    GetRate = Replace(Split(Split(s, delimiter & Chr$(34) & Chr$(58))(1), Chr$(44))(0), Chr$(125), vbNullString)
End Function
4
  • Can you include the JSON in your question? Commented May 11, 2020 at 15:15
  • And please include in which line you get that error. Commented May 11, 2020 at 15:15
  • I'd see the first answer on that question. Parsing the string by just replacing and splitting is error-prone, it can't handle a lot of valid JSON. Commented May 11, 2020 at 15:19
  • In your JSON you have tradable but your rate is called tradeable. Check your spellings. • I recommend to built in a proper error handling (VBA Error Handling – A Complete Guide) and not to do all Replace(Split(Split(… in one line as this makes it supre difficult to find in which part the error actually is. Commented May 11, 2020 at 15:19

2 Answers 2

0

You have a typo in your code:

Public Sub GetValues()
    Dim s As String, rates(), i As Long
    'Just for better reading.
    's = "{""id"":""14acfa60-c0e1-47fb-8f80-ca0831bf3b52"", _
           ""class"":""us_equity"", _
           ""exchange"":""ARCA"", _
           ""symbol"":""UVXY"", _
           ""name"":"""", _
           ""status"":""active"", _
           ""tradable"":true, _
           ""marginable"":true, _
           ""shortable"":false, _
           ""easy_to_borrow"":false}"

    '""tradable"":true, _    <<<<< ERROR in s var. In your rate array you say: "tradeable"
    ' "tradeable", _ <<<<< rate Array! (I just change it to run the code)


    s = "{""id"":""14acfa60-c0e1-47fb-8f80-ca0831bf3b52"",""class"":""us_equity"",""exchange"":""ARCA"",""symbol"":""UVXY"",""name"":"""",""status"":""active"",""tradable"":true,""marginable"":true,""shortable"":false,""easy_to_borrow"":false}"
    rates = Array("id", _
                  "class", _
                  "exchange", _
                  "symbol", _
                  "name", _
                  "status", _
                  "tradable", _
                  "marginable", _
                  "shortable", _
                  "easy_to_borrow")

    For i = LBound(rates) To UBound(rates)
        Debug.Print rates(i) & ":" & GetRate(s, rates(i))
    Next i
End Sub

Public Function GetRate(ByVal s As String, ByVal delimiter As String) As String
    'Chr$(34) = "
    'Chr$(58) = :
    'Chr$(125) = }
    'Again... better reading.
    Dim A: A = Split(s, delimiter & Chr$(34) & Chr$(58))(1)
    Dim B: B = Split(A, Chr$(44))(0)
    Dim C: C = Chr$(125)
    GetRate = Replace(B, C, vbNullString)
End Function
Sign up to request clarification or add additional context in comments.

Comments

0

First of all the issue in your code is that you have a typo: In your JSON you have tradable but your rate is called tradeable.

  1. I recommend to include a proper error handling in your function. So if something gets wrong there you don't get stuck but a error message instead.

  2. I also recommend not to have everything in one line in your function like Replace(Split(Split(… because if something gets wrong you don't know in which part it went wrong: First or second Split or the Replace. So if you do that in multiple lines (see below) then you can return a more useful error message.
    Shorter code is not necessarily faster and better. But code that is easily readable, debugable and maintainable is very good code because you will make less errors and find them quicker.

  3. I highly recommend to use meaningful variable names. Names like s for example are very bad names. If you use Json instead you always immediately see that this variable contains your JSON string.
    Meaningful variables make your code better because it is more human readable and VBA doesn't care about the extra 3 characters.

  4. Finally I would declare variables as close as possible to their first use.

So the code below is a bit longer but has much more improved readability and an error handling that gives at least a proper info if the key word you were looking for did not exist in your JSON.

Option Explicit

Public Sub GetValues()
    Dim Json As String
    Json = "{""id"":""14acfa60-c0e1-47fb-8f80-ca0831bf3b52"",""class"":""us_equity"",""exchange"":""ARCA"",""symbol"":""UVXY"",""name"":"""",""status"":""active"",""tradable"":true,""marginable"":true,""shortable"":false,""easy_to_borrow"":false}"

    Dim Rates() As Variant
    Rates = Array("id", "tradeable", "class", "exchange", "symbol", "name", "status", "tradeable", "marginable", "shortable", "easy_to_borrow")

    Dim i As Long
    For i = LBound(Rates) To UBound(Rates)
        Debug.Print Rates(i) & ":" & GetRate(Json, Rates(i))
    Next i
End Sub

Public Function GetRate(ByVal Key As String, ByVal Delimiter As String) As String
    On Error GoTo RETURN_ERR

    Dim SplitKey() As String
    SplitKey = Split(Key, Delimiter & Chr$(34) & Chr$(58))

    If UBound(SplitKey) = 0 Then
        GetRate = "KEY NOT FOUND"
        Exit Function
    End If

    Dim ValueOfKey As String
    ValueOfKey = Split(SplitKey(1), Chr$(44))(0)

    'remove } from value
    ValueOfKey = Replace(ValueOfKey, Chr$(125), vbNullString)

    'return
    GetRate = ValueOfKey

    Exit Function
RETURN_ERR:
    GetRate = "Unknown error while extracting value. Check the JSON syntax."
End Function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.