как отобразить мой объект JSON в хорошем формате в VBA Excel - PullRequest
0 голосов
/ 29 июня 2018

Я знаю отображение моего Parse Json в ячейке Excel, когда Json "прост" (когда это просто строка внутри), но теперь у меня есть String, объект и массив, и я немного растерялся .. мой JSON выглядит следующим образом:

[
    {
        "name": null,
        "type": null,
        "actions": [],
        "screen": null,
        "container": null,
        "sysid": 5,
        "uftitem": null
    },
    {
        "name": null,
        "type": null,
        "actions": [],
        "screen": null,
        "container": null,
        "sysid": 6,
        "uftitem": null
    },
    {
        "name": "UTProject5",
        "type": "type",
        "actions": [
            {
                "name": "UTProject",
                "description": "UTProject",
                "pattern": "UTProject",
                "isCheck": true,
                "sysid": 1,
                "uftaction": {
                    "sysid_uftAction": 2,
                    "code": "code uft",
                    "maxTime": 10,
                    "nbCycle": 20
                }
            },
            {
                "name": "UTProject2",
                "description": "UTProject",
                "pattern": "UTProject",
                "isCheck": true,
                "sysid": 3,
                "uftaction": {
                    "sysid_uftAction": 4,
                    "code": "code uft",
                    "maxTime": 10,
                    "nbCycle": 20
                }
            }
        ],
        "screen": {
            "name": null,
            "type": null,
            "actions": [],
            "screen": null,
            "container": null,
            "sysid": 5,
            "uftitem": null
        },
        "container": {
            "name": null,
            "type": null,
            "actions": [],
            "screen": null,
            "container": null,
            "sysid": 6,
            "uftitem": null
        },
        "sysid": 7,
        "uftitem": {
            "code": "code",
            "parentCode": "tooooz",
            "sysid": 8
        }
    },
    {
        "name": "UTProject6",
        "type": "type",
        "actions": [
            {
                "name": "UTProject",
                "description": "UTProject",
                "pattern": "UTProject",
                "isCheck": true,
                "sysid": 1,
                "uftaction": {
                    "sysid_uftAction": 2,
                    "code": "code uft",
                    "maxTime": 10,
                    "nbCycle": 20
                }
            },
            {
                "name": "UTProject2",
                "description": "UTProject",
                "pattern": "UTProject",
                "isCheck": true,
                "sysid": 3,
                "uftaction": {
                    "sysid_uftAction": 4,
                    "code": "code uft",
                    "maxTime": 10,
                    "nbCycle": 20
                }
            }
        ],
        "screen": {
            "name": null,
            "type": null,
            "actions": [],
            "screen": null,
            "container": null,
            "sysid": 5,
            "uftitem": null
        },
        "container": {
            "name": null,
            "type": null,
            "actions": [],
            "screen": null,
            "container": null,
            "sysid": 6,
            "uftitem": null
        },
        "sysid": 9,
        "uftitem": {
            "code": null,
            "parentCode": null,
            "sysid": 10
        }
    }
]

Я хотел бы получить доступ к тому, что я хочу, и отобразить его в ячейке, но я не знаю доступа к массиву и объекту.

Спасибо всем!

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Посмотрите на приведенный ниже пример. Импорт JSON.bas модуля в проект VBA для обработки JSON.

Option Explicit

Sub Test()

    Dim sJSONString As String
    Dim vJSON
    Dim sState As String
    Dim aData()
    Dim aHeader()
    Dim vResult

    ' Read JSON sample from file C:\Test\sample.json
    sJSONString = ReadTextFile("C:\Test\sample.json", 0)
    ' Parse JSON sample
    JSON.Parse sJSONString, vJSON, sState
    If sState = "Error" Then
        MsgBox "Invalid JSON"
        End
    End If
    ' Convert raw JSON to 2d array and output to worksheet #1
    JSON.ToArray vJSON, aData, aHeader
    With Sheets(1)
        .Cells.Delete
        .Cells.WrapText = False
        OutputArray .Cells(1, 1), aHeader
        Output2DArray .Cells(2, 1), aData
        .Columns.AutoFit
    End With
    ' Flatten JSON
    JSON.Flatten vJSON, vResult
    ' Convert flattened JSON to 2d array and output to worksheet #2
    JSON.ToArray vResult, aData, aHeader
    With Sheets(2)
        .Cells.Delete
        .Cells.WrapText = False
        OutputArray .Cells(1, 1), aHeader
        Output2DArray .Cells(2, 1), aData
        .Columns.AutoFit
    End With
    MsgBox "Completed"

End Sub

Sub OutputArray(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize(1, UBound(aCells) - LBound(aCells) + 1)
            .NumberFormat = "@"
            .Value = aCells
        End With
    End With

End Sub

Sub Output2DArray(oDstRng As Range, aCells As Variant)

    With oDstRng
        .Parent.Select
        With .Resize( _
                UBound(aCells, 1) - LBound(aCells, 1) + 1, _
                UBound(aCells, 2) - LBound(aCells, 2) + 1)
            .NumberFormat = "@"
            .Value = aCells
        End With
    End With

End Sub

Function ReadTextFile(sPath As String, lFormat As Long) As String

    ' lFormat -2 - System default, -1 - Unicode, 0 - ASCII
    With CreateObject("Scripting.FileSystemObject").OpenTextFile(sPath, 1, False, lFormat)
        ReadTextFile = ""
        If Not .AtEndOfStream Then ReadTextFile = .ReadAll
        .Close
    End With

End Function

Кстати, аналогичный подход применяется в следующих ответах: 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 и 19 .

0 голосов
/ 29 июня 2018

Общие сведения:

Вы можете очистить все это с помощью следующего кода, который использует JSON converter :


Примечание:

Я читаю строку JSON из листа и сохраняю в объекте через JSONConverter. Начальный объект - это коллекция. Я зацикливаю эту коллекцию и каждый вложенный уровень, используя TypeName function *, чтобы определить, какие объекты хранятся на каждом уровне. Затем я использую Select Case для соответствующей обработки этих объектов.

Более эффективным было бы создать повторно используемый класс, чтобы справиться с этим. Я видел несколько других вопросов о SO, где это делается.

* VarType на самом деле более устойчивый


Пример JSON

Example JSON


Пример вывода кода в непосредственное окно:

Вы можете выбрать способ записи в ячейку, заменив операторы Debug.Print назначениями диапазонов листов.

Sample code output


VBA:

Option Explicit
Public Sub GetInfoFromSheet()
    Dim jsonStr As String
    jsonStr = [A1]                               '<== read in from sheet
    Dim json As Object
    Set json = JsonConverter.ParseJson(jsonStr)

    Dim i As Long, j As Long, key As Variant
    For i = 1 To json.Count
        For Each key In json(i).keys
            Select Case key
            Case "name", "type"
                Debug.Print key & " " & json(i)(key)
            Case Else
                Select Case TypeName(json(i)(key))
                Case "Dictionary"
                    Dim key2 As Variant
                    For Each key2 In json(i)(key)
                        Select Case TypeName(json(i)(key)(key2))
                        Case "Collection"
                            Dim k As Long
                            For k = 1 To json(i)(key)(key2).Count
                                Debug.Print key & " " & key2 & " " & json(i)(key)(key2)(k)
                            Next k
                        Case Else
                            Debug.Print key & " " & key2 & " " & json(i)(key)(key2)
                        End Select
                    Next key2
                Case "Collection"
                    For j = 1 To json(i)(key).Count '<== "actions"
                        Dim key3 As Variant
                        For Each key3 In json(i)(key)(j).keys
                            Select Case TypeName(json(i)(key)(j)(key3))
                            Case "String", "Boolean", "Double"
                                Debug.Print key & " " & key3 & " " & json(i)(key)(j)(key3)
                            Case Else
                                Dim key4 As Variant
                                For Each key4 In json(i)(key)(j)(key3).keys
                                    Debug.Print key & " " & key3 & " " & key4 & " " & json(i)(key)(j)(key3)(key4)
                                Next key4
                            End Select
                        Next key3
                    Next j
                Case Else
                    Debug.Print key & " " & json(i)(key)
                End Select
            End Select
        Next key
    Next i
End Sub

ТЛ; др; Учебное место:

Таким образом, вышеприведенное, возможно, было немного полным, так как он получает все без особых объяснений. Ниже мы более подробно рассмотрим, как настроить таргетинг на некоторые из этих JSON и «говорить» через связанный VBA.

Для этого вы можете использовать онлайн-анализатор JSON, чтобы более четко увидеть структуру вашего JSON. Я разместил вашу JSON строку в Json Parser Online , а затем исследовал структуру в String/parseJS eval; левая часть. Доступны и другие инструменты.

Начальная вещь, которую нужно отметить, это начало "[". Самый первый, который вы можете увидеть ниже.

Start

Обозначает объект Collection, который является вашей JSON строкой при преобразовании с JsonConverter. Все остальное вложено между этой открывающей скобкой "[" и ее закрывающей копией в самом конце.

Следующее, что следует отметить, это то, что это набор словарей, поэтому все, что образует «группу» внутри, является словарем.

Dictionary

См. "{", обозначающий начало словаря?

Словарь содержит ключи "name","type","actions" и т. Д.

Первоначальное наблюдение состоит в том, что большая часть этой информации пуста, т.е. null. Мы можем игнорировать их с помощью теста IsNull (я выбираю это на основе поля "name"):

If Not IsNull(json(i)("name")) 

Мы также можем видеть, что "actions" в словарях, где "name" не null, содержит другую коллекцию словарей. Вы видите, что у нас есть "[", за которым следует "{", как описано ранее.

Collection of dictionaries

Мы можем видеть, что каждый внутренний словарь имеет ключи "name", "description" и т. Д. Мы также можем видеть, что их значения имеют разные типы данных.

Наблюдая "actions" в структуре JSON, вы можете видеть это (используя пример словаря):

  1. Строка "name":"UTProject"
  2. Строка "description":"UTProject"
  3. String "pattern":"UTProject"
  4. Boolean "isCheck":true
  5. Двухместный "sysid":1
  6. Словарь "uftaction" 'keys of ==> "sysid_uftAction":2,"code":"code uft","maxTime":10,"nbCycle":20

Итак, мы можем использовать Select Case для обработки типа данных, протестировав с TypeName

Для примитивных булевых, строковых и двойных типов данных мы можем просто напечатать их, используя ключ, например,

json(i)("actions")(j)("isCheck")

Это будет логическим результатом того, что True или False. i и j являются индексами текущей позиции в циклах как внешней, так и внутренней коллекций.

Для словаря "uftaction" мы можем зациклить его ключи:

For Each key2 In json(i)("actions")(j)(key).keys 
    Debug.Print "actions " & key & " " & key2 & " " & json(i)("actions")(j)(key)(key2)
Next key2

Конечно, вы можете получить доступ с именем ключа без петли над ключами в конце, например ::

json(i)("actions")(j)(key)("maxTime")

И везде вы можете получить доступ к определенным позициям через индекс, а не циклически, так что i и j будут заменены непосредственно на числовое значение. И key, key2 и т. Д. Можно заменить действительной литеральной строкой для любого заданного ключа .

Надеюсь, это дало вам больше понимания.

VBA:

Option Explicit
Public Sub GetInfoFromJSON()
    Dim jsonStr As String
    jsonStr = [A1]                               '<== read in from sheet
    Dim json As Object, i As Long
    Set json = JsonConverter.ParseJson(jsonStr) '<==This is a collection verified by Debug.Print TypeName(JSON)
    For i = 1 To json.Count
        If Not IsNull(json(i)("name")) Then
            'ignore the null names which have sys id only populated
            Debug.Print "name" & " " & json(i)("name")
            Debug.Print "type" & " " & json(i)("type")
            Dim j As Long
            For j = 1 To json(i)("actions").Count 'actions are a collection of dictionaries
                Dim key As Variant
                For Each key In json(i)("actions")(j).keys 'dictionary
                    'observing actions in the JSON structure you can see there are:
                    '                    String  "name":"UTProject"
                    'String "description":"UTProject",
                    'String "pattern":"UTProject",
                    'Boolean "isCheck":true,
                    'Double "sysid":1,
                    'Dictionary "uftaction" '==> "sysid_uftAction":2,"code":"code uft","maxTime":10,"nbCycle":20
                    'So we can use Select Case to handle the data type by testing with TypeName
                    Select Case TypeName(json(i)("actions")(j)(key))
                    Case "String", "Boolean", "Double" '<==good to go nothing extra needed
                        Debug.Print "actions " & key & " " & json(i)("actions")(j)(key)
                    Case Else                    ' we are dealing with uftaction which we know is a dictionary
                        Dim key2 As Variant
                        For Each key2 In json(i)("actions")(j)(key).keys '<==We know now we are looping the uftaction dictionary which has keys "sysid_uftAction","code","maxTime","nbCycle"
                            Debug.Print "actions " & key & " " & key2 & " " & json(i)("actions")(j)(key)(key2)
                        Next key2
                    End Select
                Next key
            Next j
        End If
    Next i
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...