Есть ли анализатор JSON для VB6 / VBA?

36

Я пытаюсь использовать веб-службу в VB6. Служба, которой я управляю, в настоящее время может вернуть SOAP/XML-сообщение или JSON. У меня очень трудное время выяснить, может ли тип VB6 SOAP (версия 1) обрабатывать возвращенный object - в отличие от простых типов, таких как string, int и т.д. Пока я не могу понять, что мне нужно чтобы заставить VB6 играть с возвращенными объектами.

Итак, я подумал, что могу сериализовать ответ в веб-службе как строку JSON. Существует ли JSON-парсер для VB6?

Теги:
serialization
web-services
vb6

13 ответов

38
Лучший ответ

Ознакомьтесь с JSON.org для обновленного списка (см. нижнюю часть главной страницы) парсеров JSON на разных языках. На момент написания этой статьи вы увидите ссылку на два разных парсера JSON:

  • VB-JSON

    • Когда я попытался загрузить zip файл, Windows сообщила, что данные были повреждены. Тем не менее, я смог использовать 7-zip, чтобы вытащить файлы. Оказывается, основная "папка" в zip файле не распознается как папка Windows, а 7-zip может видеть содержимое этой основной "папки", поэтому вы можете открыть это, а затем извлечь файлы соответственно.
    • Фактический синтаксис для этой библиотеки VB JSON очень прост:

      Dim p As Object
      Set p = JSON.parse(strFormattedJSON)
      
      'Print the text of a nested property '
      Debug.Print p.Item("AddressClassification").Item("Description")
      
      'Print the text of a property within an array '
      Debug.Print p.Item("Candidates")(4).Item("ZipCode")
      
    • Примечание. Мне пришлось добавить библиотеку "Microsoft Scripting Runtime" и "Microsoft ActiveX Data Objects 2.8" в качестве ссылок через "Инструменты" > "Ссылки" в редакторе VBA.
    • Примечание. Код VBJSON фактически основан на проекте кода google vba-json. Тем не менее, VBJSON promises исправлено несколько ошибок из исходной версии.
  • PW.JSON
    • На самом деле это библиотека для VB.NET, поэтому я не тратил много времени на ее изучение.
  • 0
    Есть ли способ с VB-JSON передать ему объект Class и вернуть соответствующую строку JSON? Спасибо!
  • 0
    Как вы проходите через объекты? Скажем, p.Item ("AddressClassification") содержит 3 элемента. Как я могу зациклить предметы?
Показать ещё 2 комментария
13

Построение решения ozmike, которое не сработало для меня (Excel 2013 и IE10). Причина в том, что я не мог вызывать методы открытого объекта JSON. Таким образом, его методы теперь отображаются через функции, связанные с DOMElement. Не знал, что это возможно (должно быть, это IDispatch-вещь), спасибо ozmike.

Как заявил ozmike, нет сторонних библиотек, всего 30 строк кода.

Option Explicit

Public JSON As Object
Private ie As Object

Public Sub initJson()
    Dim html As String

    html = "<!DOCTYPE html><head><script>" & _
    "Object.prototype.getItem=function( key ) { return this[key] }; " & _
    "Object.prototype.setItem=function( key, value ) { this[key]=value }; " & _
    "Object.prototype.getKeys=function( dummy ) { keys=[]; for (var key in this) if (typeof(this[key]) !== 'function') keys.push(key); return keys; }; " & _
    "window.onload = function() { " & _
    "document.body.parse = function(json) { return JSON.parse(json); }; " & _
    "document.body.stringify = function(obj, space) { return JSON.stringify(obj, null, space); }" & _
    "}" & _
    "</script></head><html><body id='JSONElem'></body></html>"

    Set ie = CreateObject("InternetExplorer.Application")
    With ie
        .navigate "about:blank"
        Do While .Busy: DoEvents: Loop
        Do While .readyState <> 4: DoEvents: Loop
        .Visible = False
        .document.Write html
        .document.Close
    End With

    ' This is the body element, we call it JSON:)
    Set JSON = ie.document.getElementById("JSONElem")

End Sub

Public Function closeJSON()
    ie.Quit
End Function

Следующий тест конструирует объект JavaScript с нуля, а затем строит его. Затем он анализирует объект назад и выполняет итерацию по его клавишам.

Sub testJson()
    Call initJson

    Dim jsObj As Object
    Dim jsArray As Object

    Debug.Print "Construction JS object ..."
    Set jsObj = JSON.Parse("{}")
    Call jsObj.setItem("a", 1)
    Set jsArray = JSON.Parse("[]")
    Call jsArray.setItem(0, 13)
    Call jsArray.setItem(1, Math.Sqr(2))
    Call jsArray.setItem(2, 15)
    Call jsObj.setItem("b", jsArray)

    Debug.Print "Object: " & JSON.stringify(jsObj, 4)

    Debug.Print "Parsing JS object ..."
    Set jsObj = JSON.Parse("{""a"":1,""b"":[13,1.4142135623730951,15]}")

    Debug.Print "a: " & jsObj.getItem("a")
    Set jsArray = jsObj.getItem("b")
    Debug.Print "Length of b: " & jsArray.getItem("length")
    Debug.Print "Second element of b: "; jsArray.getItem(1)

    Debug.Print "Iterate over all keys ..."
    Dim keys As Object
    Set keys = jsObj.getKeys("all")

    Dim i As Integer
    For i = 0 To keys.getItem("length") - 1
        Debug.Print keys.getItem(i) & ": " & jsObj.getItem(keys.getItem(i))
    Next i

    Call closeJSON
End Sub

выходы

Construction JS object ...
Object: {
    "a": 1,
    "b": [
        13,
        1.4142135623730951,
        15
    ]
}
Parsing JS object ...
a: 1
Length of b: 3
Second element of b:  1,4142135623731 
Iterate over all keys ...
a: 1
b: 13,1.4142135623730951,15
  • 0
    спасибо за работу вокруг ...
7

Я знаю, что это старый вопрос, но мой ответ, надеюсь, будет большой помощью для других, которые продолжают приходить на эту страницу после поиска "vba json".

Я нашел эту страницу очень полезной. Он предоставляет несколько совместимых с Excel классов VBA, которые обрабатывают данные обработки в формате JSON.

  • 0
    Какой из них вы бы порекомендовали?
4

ОБНОВЛЕНИЕ: Обнаруженный более безопасный способ анализа JSON, чем использование Eval, этот пост в блоге показывает опасности Eval... http://exceldevelopmentplatform.blogspot.com/2018/01/vba-parse-json-safer-with-jsonparse- and.html

Поздно к этой вечеринке, но извините, ребята, но, безусловно, самый простой способ - использовать Microsoft Script Control. Пример кода, который использует VBA.CallByName для детализации

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONParsingWithCallByName()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim sJsonString As String
    sJsonString = "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }"


    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
    Debug.Assert VBA.CallByName(objJSON, "key1", VbGet) = "value1"
    Debug.Assert VBA.CallByName(VBA.CallByName(objJSON, "key2", VbGet), "key3", VbGet) = "value3"

End Sub

На самом деле я провел серию вопросов и ответов, в которых рассматриваются темы, связанные с JSON/VBA.

В1. В Excel VBA в Windows как решить проблему точечного синтаксического анализа синтаксического анализа JSON, нарушенного поведением заглавных букв в среде IDE?

Q2 В Excel VBA в Windows, как пройти через анализируемый массив JSON?

Q3 В Excel VBA в Windows, как получить строковое представление JSON вместо "[объект объекта]" для проанализированных переменных JSON?

Q4 В Windows Excel VBA, как получить ключи JSON для предупреждения "Ошибка времени выполнения" 438 ": объект не поддерживает это свойство или метод"?

Q5 В Excel VBA в Windows, для проанализированных переменных JSON, что это за JScriptTypeInfo?

  • 1
    Работал на меня, спасибо!
  • 1
    WOW лучший ответ из 10, которые я пытался ..! Благодарю.
Показать ещё 2 комментария
4

VBA-JSON Тим Холл, лицензированный MIT и GitHub. Это еще одна вилка vba-json, которая появилась в конце 2014 года. Претензии к работе в Mac Office и Windows 32bit и 64bit.

4

Вот "Родная" библиотека VB JSON.

Можно использовать JSON, который уже находится в IE8+. Таким образом, вы не зависите от сторонней библиотеки, которая устарела и не проверена.

см. альтернативную версию amedeus здесь

Sub myJSONtest()


Dim oJson As Object
Set oJson = oIE_JSON() ' See below gets IE.JSON object

' using json objects
Debug.Print oJson.parse("{ ""hello"": ""world"" }").hello ' world
Debug.Print oJson.stringify(oJson.parse("{ ""hello"": ""world"" }")) ' {"hello":"world"}

' getting items
Debug.Print oJson.parse("{ ""key1"": ""value1"" }").key1 ' value1
Debug.Print oJson.parse("{ ""key1"": ""value1"" }").itemGet("key1") ' value1
Debug.Print oJson.parse("[ 1234, 4567]").itemGet(1) '  4567

' change  properties
Dim o As Object
Set o = oJson.parse("{ ""key1"": ""value1"" }")
o.propSetStr "key1", "value\""2"
Debug.Print o.itemGet("key1") ' value\"2
Debug.Print oJson.stringify(o) ' {"key1":"value\\\"2"}
o.propSetNum "key1", 123
Debug.Print o.itemGet("key1") ' 123
Debug.Print oJson.stringify(o) ' {"key1":123}

' add properties
o.propSetNum "newkey", 123 ' addkey! JS MAGIC
Debug.Print o.itemGet("newkey") ' 123
Debug.Print oJson.stringify(o) ' {"key1":123,"newkey":123}

' assign JSON 'objects' to properties
Dim o2 As Object
Set o2 = oJson.parse("{ ""object2"": ""object2value"" }")
o.propSetJSON "newkey", oJson.stringify(o2) ' set object
Debug.Print oJson.stringify(o) ' {"key1":123,"newkey":{"object2":"object2value"}}
Debug.Print o.itemGet("newkey").itemGet("object2") ' object2value

' change array items
Set o = oJson.parse("[ 1234, 4567]") '
Debug.Print oJson.stringify(o) ' [1234,4567]
Debug.Print o.itemGet(1)
o.itemSetStr 1, "234"
Debug.Print o.itemGet(1)
Debug.Print oJson.stringify(o) ' [1234,"234"]
o.itemSetNum 1, 234
Debug.Print o.itemGet(1)
Debug.Print oJson.stringify(o) ' [1234,234]

' add array items
o.itemSetNum 5, 234 ' add items! JS Magic
Debug.Print o.itemGet(5) ' 234
Debug.Print oJson.stringify(o) ' [1234,234,null,null,null,234]

' assign JSON object to array item
o.itemSetJSON 3, oJson.stringify(o2)  ' assign object
Debug.Print o.itemGet(3) '[object Object]
Debug.Print oJson.stringify(o.itemGet(3)) ' {"object2":"object2value"}
Debug.Print oJson.stringify(o) ' [1234,234,null,{"object2":"object2value"},null,234]


oIE_JSON_Quit ' quit IE, must shut down or the IE sessions remain.
Debug.Print oJson.stringify(o) ' can use after but but IE server will shutdown... soon
End Sub

Вы можете подключиться к IE.JSON из VB.
Создайте функцию oIE_JSON

Public g_IE As Object ' global


Public Function oIE_JSON() As Object


    ' for array access o.itemGet(0) o.itemGet("key1")
    JSON_COM_extentions = "" & _
            " Object.prototype.itemGet        =function( i ) { return this[i] }   ;            " & _
            " Object.prototype.propSetStr     =function( prop , val ) { eval('this.' + prop + '  = ""' + protectDoubleQuotes (val) + '""' )   }    ;            " & _
            " Object.prototype.propSetNum     =function( prop , val ) { eval('this.' + prop + '  = ' + val + '')   }    ;            " & _
            " Object.prototype.propSetJSON    =function( prop , val ) { eval('this.' + prop + '  = ' + val + '')   }    ;            " & _
            " Object.prototype.itemSetStr     =function( prop , val ) { eval('this[' + prop + '] = ""' + protectDoubleQuotes (val) + '""' )   }    ;            " & _
            " Object.prototype.itemSetNum     =function( prop , val ) { eval('this[' + prop + '] = ' + val )   }    ;            " & _
            " Object.prototype.itemSetJSON    =function( prop , val ) { eval('this[' + prop + '] = ' + val )   }    ;            " & _
            " function protectDoubleQuotes (str)   { return str.replace(/\\/g, '\\\\').replace(/""/g,'\\""');   }"

    ' document.parentwindow.eval dosen't work some versions of ie eg ie10?
     IEEvalworkaroundjs = "" & _
         " function IEEvalWorkAroundInit ()   { " & _
         " var x=document.getElementById(""myIEEvalWorkAround"");" & _
         " x.IEEval= function( s ) { return eval(s) } ; } ;"

    g_JS_framework = "" & _
      JSON_COM_extentions & _
      IEEvalworkaroundjs

    ' need IE8 and DOC type
    g_JS_HTML = "<!DOCTYPE html>  " & _
         " <script>" & g_JS_framework & _
                  "</script>" & _
         " <body>" & _
         "<script  id=""myIEEvalWorkAround""  onclick=""IEEvalWorkAroundInit()""  ></script> " & _
                 " HEllo</body>"

On Error GoTo error_handler

' Create InternetExplorer Object
Set g_IE = CreateObject("InternetExplorer.Application")
With g_IE
    .navigate "about:blank"
    Do While .Busy: DoEvents: Loop
    Do While .ReadyState <> 4: DoEvents: Loop
    .Visible = False ' control IE interface window
    .Document.Write g_JS_HTML
End With

Set objID = g_IE.Document.getElementById("myIEEvalWorkAround")
objID.Click ' create  eval
Dim oJson As Object

'Set oJson = g_IE.Document.parentWindow.Eval("JSON") ' dosen't work some versions of IE
Set oJson = objID.IEEval("JSON")

Set objID = Nothing
Set oIE_JSON = oJson

Exit Function
error_handler:
MsgBox ("Unexpected Error, I'm quitting. " & Err.Description & ".  " & Err.Number)
g_IE.Quit
Set g_IE = Nothing

End Function

Public Function oIE_JSON_Quit()
         g_IE.Quit
         Exit Function
End Function

Наверх, если вы найдете полезные

  • 0
    Не работает с Excel 2013 и IE10: невозможно вызвать методы для возвращенного объекта JSON. Все, что я могу сделать, это cstr(oJson) , который действительно дает [объект JSON]
  • 0
    спасибо, что у меня нет 2013 года для тестирования, но как только я это сделаю, я посмотрю на него. Если вы можете найти работу вокруг, сообщите нам.
Показать ещё 1 комментарий
3

VB6 - JsonBag, другой JSON Parser/Generator также должен быть импортирован в VBA с небольшими проблемами.

2

Вы можете написать надстройку Excel-DNA в VB.NET. Excel-DNA - это тонкая библиотека, которая позволяет писать XLL в .NET. Таким образом, вы получаете доступ ко всему .NET-юниверсу и можете использовать такие вещи, как http://james.newtonking.com/json - структуру JSON, которая десериализует JSON в любом пользовательском классе.

Если вам интересно, напишите, как создать общий Excel JSON-клиент для Excel с помощью VB.NET:

http://optionexplicitvba.com/2014/05/09/developing-a-json-excel-add-in-with-vb-net/

И вот ссылка на код: https://github.com/spreadgit/excel-json-client/blob/master/excel-json-client.dna

2

Я бы предложил использовать компонент .Net. Вы можете использовать компоненты .Net из VB6 через Interop - здесь учебник. Я предполагаю, что .Net-компоненты будут более надежными и лучше поддерживаться, чем все, что было создано для VB6.

В инфраструктуре Microsoft.Net есть компоненты, такие как DataContractJsonSerializer или JavaScriptSerializer. Вы также можете использовать сторонние библиотеки, такие как JSON.NET.

  • 0
    Спасибо за предложение. Вы отметили, что компоненты .NET будут лучше поддерживаться, чем что-либо в VB6. Это, безусловно, так. Однако (и я могу ошибаться), JSON достаточно прост, чтобы даже у VB6 не было проблем с ним. Код VB-JSON, о котором я упоминал, до сих пор работал очень хорошо.
  • 1
    @Ben JSON прост, но вы говорите, что в проекте кода Google, который использовался в качестве отправной точки, все же было несколько ошибок, так что все еще можно ошибиться.
0

это код примера vb6, проверенный в порядке, выполненные работы

из приведенных выше хороших примеров, я внес изменения и получил этот хороший результат

он может читать ключи {} и массивы []

Option Explicit
'in vb6 click "Tools"->"References" then
'check the box "Microsoft Script Control 1.0";
Dim oScriptEngine As New ScriptControl
Dim objJSON As Object

''to use it
Private Sub Command1_Click()
  MsgBox JsonGet("key1", "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }")''returns "value1"
  MsgBox JsonGet("key2.key3", "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }") ''returns "value3"
  MsgBox JsonGet("result.0.Ask", "{'result':[{'MarketName':'BTC-1ST','Bid':0.00004718,'Ask':0.00004799},{'MarketName':'BTC-2GIVE','Bid':0.00000073,'Ask':0.00000074}]}") ''returns "0.00004799"
  MsgBox JsonGet("mykey2.keyinternal1", "{mykey:1111, mykey2:{keyinternal1:22.1,keyinternal2:22.2}, mykey3:3333}") ''returns "22.1"
End Sub

Public Function JsonGet(eKey$, eJsonString$, Optional eDlim$ = ".") As String
  Dim tmp$()
  Static sJsonString$
  If Trim(eKey$) = "" Or Trim(eJsonString$) = "" Then Exit Function
  If sJsonString <> eJsonString Then
    sJsonString = eJsonString
    oScriptEngine.Language = "JScript"
    Set objJSON = oScriptEngine.Eval("(" + eJsonString + ")")
  End If
  tmp = Split(eKey, eDlim)
  If UBound(tmp) = 0 Then JsonGet = VBA.CallByName(objJSON, eKey, VbGet): Exit Function

  Dim i&, o As Object
  Set o = objJSON
  For i = 0 To UBound(tmp) - 1
    Set o = VBA.CallByName(o, tmp(i), VbGet)
  Next i
  JsonGet = VBA.CallByName(o, tmp(i), VbGet)
  Set o = Nothing
End Function

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  Set objJSON = Nothing
End Sub
0

Поскольку Json - не что иное, как струны, с ним легко можно обращаться, если мы сможем правильно им управлять, независимо от того, насколько сложна структура. Я не думаю, что для этого нужно использовать какую-либо внешнюю библиотеку или конвертер. Вот пример, где я проанализировал данные json, используя манипуляции со строками.

Sub GetJsonContent()
    Dim http As New XMLHTTP60, itm As Variant

    With http
        .Open "GET", "http://jsonplaceholder.typicode.com/users", False
        .send
        itm = Split(.responseText, "id"":")
    End With

    x = UBound(itm)

    For y = 1 To x
        Cells(y, 1) = Split(Split(itm(y), "name"": """)(1), """")(0)
        Cells(y, 2) = Split(Split(itm(y), "username"": """)(1), """")(0)
        Cells(y, 3) = Split(Split(itm(y), "email"": """)(1), """")(0)
        Cells(y, 4) = Split(Split(itm(y), "street"": """)(1), """")(0)
    Next y
End Sub
0

Формула в клетке EXCEL

=JSON2("{mykey:1111, mykey2:{keyinternal1:22.1,keyinternal2:22.2}, mykey3:3333}", "mykey2", "keyinternal2")

ОТОБРАЖАЕТ: 22,2

=JSON("{mykey:1111,mykey2:2222,mykey3:3333}", "mykey2")

ПОКАЗЫВАЕТ: 2222

  • ИНСТРУКЦИИ:
  • Шаг 1. нажмите ALT + F11
  • Шаг 2. Вставить → Модуль
  • Шаг 3. инструменты → ссылки → отметьте Microsoft Script Control 1.0
  • Step4. вставьте это ниже.
  • Step5. ALT + Q закрыть окно VBA.

Сервис → Ссылки → Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\MSScript.ocx

Public Function JSON(sJsonString As String, Key As String) As String
On Error GoTo err_handler

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")

    JSON = VBA.CallByName(objJSON, Key, VbGet)

Err_Exit:
    Exit Function

err_handler:
    JSON = "Error: " & Err.Description
    Resume Err_Exit

End Function


Public Function JSON2(sJsonString As String, Key1 As String, Key2 As String) As String
On Error GoTo err_handler

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    Dim objJSON As Object
    Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")

    JSON2 = VBA.CallByName(VBA.CallByName(objJSON, Key1, VbGet), Key2, VbGet)

Err_Exit:
    Exit Function

err_handler:
    JSON2 = "Error: " & Err.Description
    Resume Err_Exit

End Function
0

Используя функции JavaScript для разбора JSON, поверх ScriptControl, мы можем создать парсер в VBA, который будет перечислять каждую точку данных внутри JSON. Независимо от того, насколько вложенной или сложной структура данных, пока мы предоставляем действительный JSON, этот анализатор вернет полную древовидную структуру.

JavaScripts Методы Eval, getKeys и getProperty предоставляют строительные блоки для проверки и чтения JSON.

В сочетании с рекурсивной функцией в VBA мы можем перебирать все ключи (вплоть до n-го уровня) в строке JSON. Затем, используя элемент управления Tree (используемый в этой статье) или словарь или даже на простом листе, мы можем упорядочить данные JSON по мере необходимости.

Полный код VBA здесь. Используя функции JavaScript для разбора JSON, поверх ScriptControl, мы можем создать парсер в VBA, который будет перечислять каждую точку данных внутри JSON. Независимо от того, насколько вложенной или сложной структура данных, пока мы предоставляем действительный JSON, этот анализатор вернет полную древовидную структуру.

JavaScripts Методы Eval, getKeys и getProperty предоставляют строительные блоки для проверки и чтения JSON.

В сочетании с рекурсивной функцией в VBA мы можем перебирать все ключи (вплоть до n-го уровня) в строке JSON. Затем, используя элемент управления Tree (используемый в этой статье) или словарь или даже на простом листе, мы можем упорядочить данные JSON по мере необходимости.

Полный код VBA здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню