Git Product home page Git Product logo

vba-json-parser's Introduction

VBA JSON Parser

release last-commit downloads code-size language license gitter tweet

Backus-Naur Form JSON Parser based on RegEx for VBA.

Purpose and Features

  • Parsing JSON string to a structure of nested Dictionaries and Arrays. JSON Objects {} are represented by Dictionaries, providing .Count, .Exists(), .Item(), .Items, .Keys properties and methods. JSON Arrays [] are the conventional zero-based VB Arrays, so UBound() + 1 allows to get the number of elements. Such approach makes easy and straightforward access to structure elements (parsing result is returned via variable passed by ref to sub, so that both an array and a dictionary object can be returned).
  • Serializing JSON structure with beautification.
  • Building 2D Array based on table-like JSON structure.
  • Flattening and unflattening JSON structure.
  • Serializing JSON structure into YAML format string.
  • Parser complies with JSON Standard.
  • Allows few non-stantard features in JSON string parsing: single quoted and unquoted object keys, single quoted strings, capitalised True, False and Null constants, and trailing commas.
  • Invulnerable for malicious JS code injections.

Compatibility

Supported by MS Windows Office 2003+ (Excel, Word, Access, PowerPoint, Publisher, Visio etc.), CorelDraw, AutoCAD and many others applications with hosted VBA. And even VB6.

Deployment

Start from example project, Excel workbook is available for downloading in the latest release.

Or

Import JSON.bas module into the VBA Project for JSON processing. Need to include a reference to Microsoft Scripting Runtime.

How to import?

Download and save JSON.bas to a file - open the page with JSON.bas code, right-click on Raw button, choose Save link as... (for Chrome):

download

Import JSON.bas into the VBA Project - open Visual Basic Editor by pressing Alt+F11, right-click on Project Tree, choose Import File, select downloaded JSON.bas:

import

Or you may drag'n'drop downloaded JSON.bas from explorer window (or desktop) directly into the VBA Project Tree.

How to add reference?

Open Visual Basic Editor by pressing Alt+F11, click Menu - Tools - References, scroll down to Microsoft Scripting Runtime and check it, press OK:

add reference

attention MS Word Object Library compatibility note

When referencing both Microsoft Scripting Runtime and Microsoft Word Object Library make sure that Microsoft Scripting Runtime located above Microsoft Word Object Library in the the list, if not so then ajust the position by clicking Priority arrows to the right of the list.

Microsoft Scripting Runtime and Microsoft Word Object Library

Otherwise you have to change all Dictionary references to Scripting.Dictionary in your VBA code.

Usage

Here is simple example for MS Excel, put the below code into standard module:

Option Explicit

Sub Test()
    
    Dim sJSONString As String
    Dim vJSON
    Dim sState As String
    Dim vFlat
    
    ' Retrieve JSON response
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "http://trirand.com/blog/phpjqgrid/examples/jsonp/getjsonp.php?qwery=longorders&rows=1000", True
        .Send
        Do Until .ReadyState = 4: DoEvents: Loop
        sJSONString = .ResponseText
    End With
    ' Parse JSON response
    JSON.Parse sJSONString, vJSON, sState
    ' Check response validity
    Select Case True
        Case sState <> "Object"
            MsgBox "Invalid JSON response"
        Case Not vJSON.Exists("rows")
            MsgBox "JSON contains no rows"
        Case Else
            ' Convert JSON nested rows array to 2D Array and output to worksheet #1
            Output ThisWorkbook.Sheets(1), vJSON("rows")
            ' Flatten JSON
            JSON.Flatten vJSON, vFlat
            ' Convert to 2D Array and output to worksheet #2
            Output ThisWorkbook.Sheets(2), vFlat
            ' Serialize JSON and save to file
            CreateObject("Scripting.FileSystemObject") _
                .OpenTextFile(ThisWorkbook.Path & "\sample.json", 2, True, -1) _
                .Write JSON.Serialize(vJSON)
            ' Convert JSON to YAML and save to file
            CreateObject("Scripting.FileSystemObject") _
                .OpenTextFile(ThisWorkbook.Path & "\sample.yaml", 2, True, -1) _
                .Write JSON.ToYaml(vJSON)
            MsgBox "Completed"
    End Select
    
End Sub

Sub Output(oTarget As Worksheet, vJSON)
    
    Dim aData()
    Dim aHeader()
    
    ' Convert JSON to 2D Array
    JSON.ToArray vJSON, aData, aHeader
    ' Output to target worksheet range
    With oTarget
        .Activate
        .Cells.Delete
        With .Cells(1, 1)
            .Resize(1, UBound(aHeader) - LBound(aHeader) + 1).Value = aHeader
            .Offset(1, 0).Resize( _
                    UBound(aData, 1) - LBound(aData, 1) + 1, _
                    UBound(aData, 2) - LBound(aData, 2) + 1 _
                ).Value = aData
        End With
        .Columns.AutoFit
    End With
    
End Sub

More Examples

You can find some usage examples on SO.

Beta

Here are some drafts being under development and not fully tested, any bugs detected and suggestions on improvement are welcome in issues.

Extension Beta

jsonExt.bas. Some functions available as draft to add flexibility to computations and facilitate processing of JSON structure:

toArray() - advanced converting JSON structure to 2d array, enhanced with options explicitly set columns names and order in the header and forbid or permit new columns addition.
filter() - fetching elements from array or dictionary by conditions, set like conds = Array(">=", Array("value", ".dimensions.height"), 15).
sort() - ordering elements of array or dictionary by value of element by path, set like ".dimensions.height".
slice() - fetching a part of array or dictionary by beginning and ending indexes.
selectElement() - fetching an element from JSON structure by path, set like ".dimensions.height".
joinSubDicts() - merging properties of subdictionaries from one dictionary to another dictionary.
joinDicts() - merging properties from one dictionary to another dictionary.
nestedArraysToArray() - converting nested 1d arrays representing table data with header array into array of dictionaries.

JSON To XML DOM converter Beta

JSON2XML.bas. Converting JSON string to XML string and loading it into XML DOM (instead of building a structure of dictionaries and arrays) can significantly increase performance for large data sets. Further XML DOM data processing is not yet covered within current version, and can be implemented via DOM methods and XPath.

Douglas Crockford json2.js implementation for VBA Beta

jsJsonParser parser is essential for parsing large amounts of JSON data in VBA, it promptly parses strings up to 10 MB and even larger. This implementation built on douglascrockford/JSON-js, native JS code runs on IE JScript engine hosted by htmlfile ActiveX. Parser is wrapped into class module to make it possible to instantiate htmlfile object and create environment for JS execution in Class_Initialize event prior to parsing methods call.

There are two methods available to parse JSON string: parseToJs(sample, success) and parseToVb sample, jsJsonData, result, success, as follows from the names you can parse to native JS entities of JScriptTypeInfo type, or parse to VBA entities which are a structure of nested Dictionaries and Arrays as described in Purpose and Features section. Access to native JS entities is possible using jsGetProp() and jsGetType() methods. For JS entities processing you have to have at least common knowledge of JavaScript Objects and Arrays.

Also you can parse to JS entities first, then make some processing and finally convert to VBA entities by calling parseToVb , jsJsonData, result, success for further utilization. JS entities can be serialized to JSON string by stringify(jsJsonData, spacer) method, if you need to serialize VBA entities, then use JSON.Serialize() function from JSON.bas module. If you don't want to mess with JS entities, simply use parseToVb sample, , result, success method. Note that convertion to VBA entities will take extra time.

There are few examples in jsJsonParser_v0.1.1.xlsm workbook of the last release

vba-json-parser's People

Contributors

omegastripes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vba-json-parser's Issues

Escaped characters in a string

Unicode characters of the form \u1234 and other escaped stuff like \n

This part of the string-matching pattern
""(?:\\""|[^""])*""
Should be something like
""(?:[^\\""]+|\\[""\\/bfnrt]|\\u[0-9a-fA-F]{4})*""
ie (non-escaped chars|\n|\u1234)*
?

https://www.crockford.com/mckeeman.html
`string
'"' characters '"'

characters
""
character characters

character
'0020' . '10FFFF' - '"' - ''
'' escape

escape
'"'
''
'/'
'b'
'f'
'n'
'r'
't'
'u' hex hex hex hex

hex
digit
'A' . 'F'
'a' . 'f'`

"Invalid use of New keyword" in json_ParseObject

Hi there,

I tried to test out VBA-JSON and used this simple macro from your examples:

Sub ExampleUsingJsonParser()
    Dim Json As Object
    Set Json = JsonConverter.ParseJson("{""a"":123,""b"":[1,2,3,4],""c"":{""d"":456}}")

    MsgBox (Json("c")("e"))

End Sub

However, while executing the macro I am getting the "Invalid use of New keyword" error in here:

Private Function json_ParseObject(json_String As String, ByRef json_Index As Long) As Dictionary
    Dim json_Key As String
    Dim json_NextChar As String

    Set json_ParseObject = New Dictionary
    json_SkipSpaces json_String, json_Index
    If VBA.Mid$(json_String, json_Index, 1) <> "{" Then
        Err.Raise 10001, "JSONConverter", json_ParseErrorMessage(json_String, json_Index, "Expecting '{'")
    Else
        json_Index = json_Index + 1

        Do
            json_SkipSpaces json_String, json_Index
            If VBA.Mid$(json_String, json_Index, 1) = "}" Then
                json_Index = json_Index + 1
                Exit Function
            ElseIf VBA.Mid$(json_String, json_Index, 1) = "," Then
                json_Index = json_Index + 1
                json_SkipSpaces json_String, json_Index
            End If

            json_Key = json_ParseKey(json_String, json_Index)
            json_NextChar = json_Peek(json_String, json_Index)
            If json_NextChar = "[" Or json_NextChar = "{" Then
                Set json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
            Else
                json_ParseObject.Item(json_Key) = json_ParseValue(json_String, json_Index)
            End If
        Loop
    End If
End Function

precisely in this line: Set json_ParseObject = New Dictionary.

I have imported JsonCoverter.bas into my project and added reference to Microsoft Scripting Runtime, so everything should work fine.

I am using MS VBA 7.1.

Any ideas?

Parsing escaped \

Hello,
I have an issue where an escaped anti slash is still interpreted as a special character

my input:

sValue = "[{""$id"":""1"",""$type"":""InputFile, Project_Data"",""InputFileID"":40164,""Name"":""BE5642378-900"",""FilePath"":""\\\\res.company.corp\\DCE\\av\\ateri\\BE5642378-900.CATPart"",""Main"":""ateri""}]"

the attribute FilePath should become \\res.company.corp\DCE\av...
but instead the \r is replace by a line return

I don't think it's an adequate solution, but all I could find was to change in the Sub Retrieve, the Case "s" with this code

    vTransfer = Replace(Mid(sTokenValue, 2, Len(sTokenValue) - 2), "\\", "_Escaped_Anti_Slash_") 'Added this line
    vTransfer = Replace(Replace(Replace(Replace(Replace(Replace(Replace( _
                    vTransfer, _
                    "\""", """"), _
                    "\/", "/"), _
                    "\b", Chr(8)), _
                    "\f", Chr(12)), _
                    "\n", vbLf), _
                    "\r", vbCr), _
                    "\t", vbTab) 'removed a replace here:  "\\", "\"), _
    vTransfer = Replace(vTransfer, "_Escaped_Anti_Slash_", "\") 'Added this line

I think a regex would be better, but couldn't find how to implement it

Type mismatch

Hi,

Please, could you tell me how I can access to the last element of my JSON string please ?

image

I tried with the following code, but the vJSON seems not correct :

image

Thx

there is a error aftering use 2 times

hi
I referenceed the JSON for 2 times in the same module, then threw a error that it said "This array is fixed or temporarily locked".the follow is code example:

Dim subtitles_json_one As String, vJson, vStateAs String
Dim subtitles_json_two As String
JSON.Parse subtitles_json_one, vJson, vState
JSON.Parse subtitles_json_two, vJson, vState 

I know why it's erroring out. This error occurs because subtitles_json_one generates a vjson, and continues to use the vjson that has not been reset in subtitles_json_two. I would like to know how to reset vjson so that I can re-assign vjson. I have tried similar erase statement but still can't reset vjson. If you continue without resetting vjson, you will get an error that it said "This array is fixed or temporarily"
I know I can redefine a new variable in place of vjson, but apparently I'm just bypassing such issues, but I can't figure out how to reset vjson

The code below is the solution, by defining new variables, but that's not what I want, what I want is how to be able to reset the data of the vjson

Dim subtitles_json_one As String, vJson, vState As String
Dim subtitles_json_two As String, sJson, sState As String
JSON.Parse subtitles_json_one, vJson, vState
JSON.Parse subtitles_json_two, sJson, sState 

Data being trimmed / truncated ?

Hi all,

I've managed to get an example working with this package but the source JSON data I'm using is being truncated when it is outputted to an Excel sheet. See the below images which shows the the precision of the latitude/longitude values being trimmed, as well as the '0' being dropped from the phone number:

raw_json

truncated_data

I'm using the following code:

    ' Parse JSON sample
    JSON.Parse sJSONString, vJSON, sState
    If sState = "Error" Then MsgBox "Invalid JSON": End
    
    ' Convert JSON to 2D Array
    JSON.ToArray vJSON, aData, aHeader
      
    ' Output to worksheet #1
    Output aHeader, aData, ThisWorkbook.Sheets(2)
    MsgBox "Completed"
Sub Output(aHeader, aData, oDestWorksheet As Worksheet)
    With oDestWorksheet
        .Activate
        .Cells.Delete
        With .Cells(1, 1)
            .Resize(1, UBound(aHeader) - LBound(aHeader) + 1).Value = aHeader
            .Offset(1, 0).Resize( _
                    UBound(aData, 1) - LBound(aData, 1) + 1, _
                    UBound(aData, 2) - LBound(aData, 2) + 1 _
                ).Value = aData
        End With
        .Columns.AutoFit
    End With
End Sub

How can I debug this issue to work out what is happening?

Thank you

Does this work for anybody?

This code looks great, but I can't get it to work at all. I've downloaded and imported the bas file part and copied the example into a standard module. When I run the "TEST" module, I immediately get "Compile Error: Expected: line number or label or statement or end of statement" on the first character of

Am I missing something obvious?

Thanks for any help

Make SerializeElement work with range().value output multidimensional array

The current code only handles single dimensional, 0 based arrays. The code below that I'm too lazy to PR ( and might want some cleanup ) makes it correctly encode json from a structure with one of the two dimensional 1 based arrays that range returns. Test cases would be nice, etc, but I'm on deadline and can't be bothered :(

        Case Is >= vbArray
            If UBound(vElement) = -1 Then
                .item(.Count) = "[]"
            Else
                .item(.Count) = "[" & vbCrLf
                dimensions = Bounds(vElement).Count
                For i = LBound(vElement) To UBound(vElement)
                    If dimensions > 1 Then ' Note that this works only for 2 dimensions, which is what range returns
                        .item(.Count) = sIndent & "["
                       For j = LBound(vElement, 2) To UBound(vElement, 2)
                            .item(.Count) = sIndent & vbTab
                            SerializeElement vElement(i, j), sIndent & vbTab
                            If Not (j = UBound(vElement, 2)) Then .item(.Count) = ","
                            .item(.Count) = vbCrLf
                        Next
                        .item(.Count) = sIndent & "]"
                        If Not (i = UBound(vElement)) Then .item(.Count) = ","
                    Else
                        .item(.Count) = sIndent & vbTab
                        SerializeElement vElement(i), sIndent & vbTab
                        If Not (i = UBound(vElement)) Then .item(.Count) = ","
                        .item(.Count) = vbCrLf
                    End If
                Next
                .item(.Count) = sIndent & "]"
            End If

and from a StackOverflow answer:

Function Bounds(A As Variant) As Collection
Dim c As New Collection
Dim v As Variant, i As Long

  On Error GoTo exit_function
  i = 1
  Do While True
      v = Array(LBound(A, i), UBound(A, i))
      c.Add v
      i = i + 1
  Loop

exit_function:
Set Bounds = c
End Function

I got stuck on the child list

@omegastripes Hi, I got stuck and I would ask for help. A Json resp. I have a "..line" child, it's a variable number, I want to write this child's "lineNumber", "lineDescription" to the table. No matter how hard I try, I get here:

`...Dim i As Integer
Dim Item As Variant
'head = Array("Main.Lines.line[0].lineDescription")
Dim rows As Dictionary
Set rows = New Dictionary
For i = 0 To UBound(data)
For Each Item In data(i)("Main")("Lines")("line")
'Debug.Print i

    Set data(i)("Main.Lines.line[i]") = rows
     Next
Next
' specify fields neccessary to display
head = Array("Number", "Main.Lines.line.lineDescription", "rows?[i]")
 jsonExt.pushItem data, rows, , False

Dim body()
jsonExt.toArray data, body, head, True
' output arrays to worksheet

With ThisWorkbook.Sheets("szamla")
    .Activate
    .Cells.Delete
    With .Cells(1, 1)
        .Resize(1, UBound(head) - LBound(head) + 1).Value = head
        .Offset(1, 0).Resize( _
                UBound(body, 1) - LBound(body, 1) + 1, _
                UBound(body, 2) - LBound(body, 2) + 1 _
            ).Value = body
    End With...

`

parser become very slow

Hi, suddenly, it becomes very slow to parse JSONString to Dictionary. I've tested with multiple computers. Did you notice this issue?

vJSON.Item is failing

i have a simple json file..
{"employee" : {"name" :"vivek"}}
i am trying to retrieve the employee from this json.
i do the below command
JSON.Parse sJSONString, vJSON, sState
and later do
sCont = vJSON("employee")

i get the below error. please help

image

Invalid JSON response

Hello!

I'm getting the error "Invalid JSON response" when I try to parse the JSON at the end.
Could it be related to some of the fields having HTML code inside? IE (Parsed with jsonlint.com):
"headword_full": "Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"phonetics\">['a?nha?t]<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span>",

Thank you!

[{"lang":"de","hits":[{"type":"entry","opendict":false,"roms":[{"headword":"Einheit","headword_full":"Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"phonetics\">['a?nha?t]<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span>","wordclass":"noun","arabs":[{"header":"1. Einheit <span class=\"topic\"><acronym title=\"auch\">a.<\/acronym> <acronym title=\"military\">MIL<\/acronym>, <acronym title=\"politics\">POL<\/acronym>, <acronym title=\"law\">LAW<\/acronym><\/span>:","translations":[{"source":"<strong class=\"headword\">Einheit<\/strong>","target":"unidad <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span>"},{"source":"<span class=\"idiom_proverb\"><strong class=\"tilde\">Einheit<\/strong> der Rechtsordnung<\/span>","target":"unidad del ordenamiento jurídico"},{"source":"<span class=\"idiom_proverb\">motorische <strong class=\"tilde\">Einheit<\/strong><\/span> <span class=\"topic\"><acronym title=\"medicine\">MED<\/acronym><\/span>","target":"unidad motora"},{"source":"<span class=\"idiom_proverb\">untrennbare rechtliche <strong class=\"tilde\">Einheit<\/strong><\/span>","target":"unidad jurídica indivisible"},{"source":"<span class=\"idiom_proverb\">die deutsche <strong class=\"tilde\">Einheit<\/strong><\/span>","target":"la unidad alemana"}]},{"header":"2. Einheit <span class=\"topic\"><acronym title=\"telecommunications\">TELEC<\/acronym><\/span>:","translations":[{"source":"<strong class=\"headword\">Einheit<\/strong>","target":"paso <span class=\"genus\"><acronym title=\"masculine\">m<\/acronym><\/span> de contador"}]}]}]},{"type":"entry","opendict":false,"roms":[{"headword":"Ausgabe-Einheit","headword_full":"Ausgabe-Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> <span class=\"topic\"><acronym title=\"computing\">COMPUT<\/acronym><\/span>","wordclass":"noun","arabs":[{"header":"","translations":[{"source":"<strong class=\"headword\">Ausgabe-Einheit<\/strong>","target":"unidad <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> de salida"}]}]}]},{"type":"entry","opendict":false,"roms":[{"headword":"Eingabe-Einheit","headword_full":"Eingabe-Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> <span class=\"topic\"><acronym title=\"computing\">COMPUT<\/acronym><\/span>","wordclass":"noun","arabs":[{"header":"","translations":[{"source":"<strong class=\"headword\">Eingabe-Einheit<\/strong>","target":"unidad <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> de entrada"}]}]}]},{"type":"entry","opendict":false,"roms":[{"headword":"Hardware-Einheit","headword_full":"Hardware-Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> <span class=\"topic\"><acronym title=\"computing\">COMPUT<\/acronym><\/span>","wordclass":"noun","arabs":[{"header":"","translations":[{"source":"<strong class=\"headword\">Hardware-Einheit<\/strong>","target":"unidad <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> de hardware"}]}]}]},{"type":"entry","opendict":false,"roms":[{"headword":"SI-Einheit","headword_full":"SI-Einheit <span class=\"flexion\">&lt;-, -en&gt;<\/span> <span class=\"wordclass\"><acronym title=\"noun\">N<\/acronym><\/span> <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span>","wordclass":"noun","arabs":[{"header":"","translations":[{"source":"<strong class=\"headword\">SI-Einheit<\/strong>","target":"unidad <span class=\"genus\"><acronym title=\"feminine\">f<\/acronym><\/span> SI"}]}]}]}]}]

How to use it?

Please, can you write some examples of how to use it?

Any documentation will be really appreciated.

Подскажите как использовать для ответов сервиса КЛАДР в облаке

Здравствуйте, вчера нашел Ваш модуль
не подскажите как с помощью него распарсить JSON ответ от Кладр по подбору адреса

http://kladr-api.ru/integration/
пример их запроса
http://kladr-api.ru/api.php?query=%D0%90%D1%80%D1%85&contentType=city&withParent=1&limit=2

результаты массива первого уровня удалось достать

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "http://kladr-api.ru/api.php?query=%D0%90%D1%80%D1%85&contentType=city&withParent=1&limit=2", False
        .send
        sJSONString = .responseText
    End With
    JSON.Parse sJSONString, vJSON, sState
    vJSON = vJSON("result")
    JSON.ToArray vJSON, aData, aHeader

а как добраться к вложенным в result массивам parents

{
    "searchContext": {                      // Объект с переданными серверу параметрами
        "query": "Арх",
        "contentType": "city",
        "withParent": 1,
        "limit": 2
    },
    "result": [                             // Массив полученных объектов заданного типа (населённые пункты)
        {
            "id": "2900000100000",          // Код объекта
            "name": "Архангельск",          // Название объекта
            "zip": null,                    // Почтовый индекс объекта
            "type": "Город",                // Тип объекта полностью
            "typeShort": "г",               // Тип объекта коротко
            "okato": "11401000000",         // Код ОКАТО
            "parents": [                    // Массив родительских объектов (если был передан параметр withParent)
                {
                    "id": "2900000000000",
                    "name": "Архангельская",

Won't run after import

After import to excel, the code won't run and it seems there's an extra End Sub in the code. Also, after I delete the extra End Sub. Run JSON.Serialize(someDictionary) will result in error.

Parser is failing to handle a JSON containing git issues

Hello,

I want to convert a set of git issues (exported using a simple cURL command) from the output JSON file into a flattened Excel worksheet. Attached is the structure of JSON file:
sample-issues.zip

Using the sample test code, I get the following error "Invalid JSON response". The JSON file seems to have been parsed correctly (see watch window below) however the type of sState is Array while Object is expected in the provided example. Do you have a sample VBA code to flatten any JSON structure to a worksheet (something similar to this online converter https://www.convertcsv.com/json-to-csv.htm)?

image

Type Mismatch for JSON format in a list/array

When attempting to parse a JSON type that is encapsulated in a list with [...] as shown below rather than key value pair, {...}, JSON.parse raises a runtime error for type mismatch on a ReDim line of an array.

Format

[
  {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
  },
  {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
  },
  {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
  }
]

Reprex

Sub ParseCLDataJSON()
    Dim url As String, strJSON As String, strState As String
    Dim parsedJSON As Object, element As Variant
     
    url = "https://raw.githubusercontent.com/ParfaitG/DATA_MIGRATION/master/JSON/JSONtoCSV/CLData.json"
   
    ' Retrieve JSON response
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", url, True
        .Send
        Do Until .ReadyState = 4: DoEvents: Loop
         strJSON = .ResponseText
    End With
    
    ' Parse JSON response
    JSON.Parse strJSON, parsedJSON, strState
    
    ' ITERATE THROUGH DATA ROWS, APPENDING TO TABLE
    For Each element In parsedJSON
        Debug.Print element("user")
        Debug.Print element("category")
        Debug.Print element("city")
        Debug.Print element("post")
        Debug.Print element("time")
        Debug.Print element("link")
    Next element

    Set element = Nothing: Set parsedJSON = Nothing
End Sub

Error

Run-time error '13': Type mismatch

Error detecting structure in JSON.Parse

I'm getting error in:
JSON.Parse sJSONString, vJSON, sState

vJSON is coming Null from this JSON. I checked Sub Parse and it appears that it does not recognize the structure. When I write Tab characters it works.
Does not works
image

Works
image

Please, be notified that is the same data!

selectElement() bug with certain paths

Fully realize that selectElement() is in beta, but figured I should still mention this strange behavior.

So when I call selectElement() using the following it crashes silently.

Dim durationRawValVal
Dim durationRawValExists
Dim tempi As Integer
tempi = 0
Dim elementpicker As String
elementpicker = ".rows[0].elements[" & tempi & "].duration.value"
jsonExt.selectElement vJSON, elementpicker, durationRawValVal, durationRawValExists

Tracing the crash with the debugger points to line 740 in jsonExt. I wonder if it is an issue with reassigning the parameter "path".

I was able to work around the issue by adding a new variable to assign parts to. Not sure if this causes other errors or if it is the cleanest solution.

Public Sub selectElement(root, path, entry, exists)
 ...
    
    Dim elt
    Dim i
    Dim pathArray
    If Not IsArray(path) Then
        Dim parts
        If path = "" Then
...
        End If
        If Not exists Then Exit Sub

        pathArray = parts
    Else
        pathArray = path        
    End If
    assign root, entry
    exists = True
    For i = 0 To UBound(pathArray)
        exists = False
        elt = pathArray(i)
        If elt = "" Then
            exists = True
...
    
End Sub

camelCase

Going to change JSON.bas to more common camelCase from Hungarian notation, what do you think?






* "native" means such built-in object model methods and properties names like .Add, .Copy, .Delete, .Count, .Item, .Parent and many others, which are PascalCase by default.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.