Есть ли анализатор JSON для VB6 / VBA? - PullRequest
38 голосов
/ 06 мая 2010

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

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

Ответы [ 14 ]

39 голосов
/ 06 мая 2010

Проверьте 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» и «Объекты данных Microsoft ActiveX 2.8» в качестве ссылок через Инструменты> Ссылки в редакторе VBA.
    • Примечание. Код VBJSON фактически основан на проекте Google Code vba-json . Тем не менее, VBJSON обещает несколько исправлений ошибок из оригинальной версии.
  • PW.JSON
    • На самом деле это библиотека для VB.NET , поэтому я не стал тратить много времени на ее изучение.
14 голосов
/ 10 февраля 2014

Построение решения на озмике, которое у меня не сработало (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
7 голосов
/ 14 июня 2012

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

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

5 голосов
/ 11 июля 2016

ОБНОВЛЕНИЕ: Обнаруженный более безопасный способ анализа 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.

Q1 В 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?

4 голосов
/ 09 июля 2015

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

4 голосов
/ 11 ноября 2013

Вот "родная" библиотека VSON JSON.

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

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

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

Проголосуйте, если сочтете нужным

3 голосов
/ 21 октября 2013

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

2 голосов
/ 16 июня 2017

Поскольку 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
2 голосов
/ 11 мая 2014

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

Если вам интересно, вот описание того, как создать универсальный JSON-клиент Excel для 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 голосов
/ 07 мая 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...