J'essaie de consommer un service Web dans VB6. Le service - que je contrôle - peut actuellement renvoyer un message SOAP/XML ou JSON. J'ai beaucoup de difficulté à déterminer si le type SOAP de VB6 (version 1) peut gérer une valeur retournée object
- par opposition aux types simples tels que string
, int
, etc. pour que VB6 joue avec les objets retournés.
J'ai donc pensé pouvoir sérialiser la réponse dans le service Web en tant que chaîne JSON. Un analyseur JSON existe-t-il pour VB6?
Consultez JSON.org pour une liste à jour (voir au bas de la page principale) d’analyseurs JSON dans de nombreuses langues. Au moment d'écrire ces lignes, vous verrez un lien vers deux analyseurs JSON différents:
La syntaxe réelle de cette bibliothèque JSON VB est très simple:
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")
S'appuyant sur la solution ozmike, qui ne fonctionnait pas pour moi (Excel 2013 et IE10) . La raison en est que je ne pouvais pas appeler les méthodes sur l'objet JSON exposé . Ses méthodes sont maintenant exposées au travers de fonctions attachées à un DOMElement . Je ne savais pas que c'était possible (ce doit être cette chose-IDispatch), merci Ozmike.
Comme Ozmike l'a déclaré, pas de bibliothèque tierce partie, seulement 30 lignes de code.
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
Le test suivant construit un objet JavaScript à partir de rien, puis le hiérarchise . Il analyse ensuite l'objet et effectue une itération sur ses clés.
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
les sorties
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
Je sais que c’est une vieille question, mais ma réponse sera d’une grande aide pour ceux qui continuent à consulter cette page après avoir recherché "vba json".
J'ai trouvé cette page très utile. Il fournit plusieurs classes VBA compatibles Excel qui traitent du traitement des données au format JSON.
MISE À JOUR: trouvé un moyen plus sûr d'analyser JSON que d'utiliser Eval, ce billet de blog montre les dangers d'Eval ... http://exceldevelopmentplatform.blogspot.com/2018/01/vba-parse-json-safer- avec-jsonparse-and.html
En retard pour cette soirée, mais désolé les gars, mais de loin le moyen le plus simple consiste à utiliser Microsoft Script Control. Un exemple de code utilisant VBA.CallByName pour accéder au détail
'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
J'ai en fait préparé une série de questions et réponses sur des sujets liés à JSON/VBA.
Q2 Dans Excel VBA sous Windows, comment parcourir une matrice JSON analysée?
Voici une bibliothèque JSON "native" VB.
Il est possible d'utiliser JSON déjà présent dans IE8 +. De cette façon, vous n'êtes pas dépendant d'une bibliothèque tierce périmée et non testée.
voir la version alternative de amedeus ici
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
Vous pouvez créer un lien vers IE.JSON à partir de VB.
Créer une fonction 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
Votez si vous trouvez utile
VB6 - JsonBag, un autre analyseur/générateur JSON devrait également pouvoir être importé dans VBA avec peu de problèmes.
Vous pouvez écrire un complément Excel-DNA dans VB.NET. Excel-DNA est une bibliothèque mince qui vous permet d'écrire des fichiers XLL dans .NET. De cette façon, vous avez accès à l’ensemble de l’univers .NET et pouvez utiliser des éléments tels que http://james.newtonking.com/json - un framework JSON qui désérialise JSON dans n’importe quelle classe personnalisée.
Si cela vous intéresse, voici une description de la création d'un client JSON Excel générique pour Excel à l'aide de VB.NET:
http://optionexplicitvba.com/2014/05/09/developing-a-json-Excel-add-in-with-vb-net/
Et voici le lien vers le code: https://github.com/spreadgit/Excel-json-client/blob/master/Excel-json-client.dna
Je suggère d'utiliser un composant .Net. Vous pouvez utiliser des composants .Net à partir de VB6 via Interop - voici un tutorial . Mon hypothèse est que les composants .Net seront plus fiables et mieux pris en charge que tout ce qui est produit pour VB6.
Il existe des composants dans le framework Microsoft .Net tels que DataContractJsonSerializer ou JavaScriptSerializer . Vous pouvez également utiliser des bibliothèques tierces telles que JSON.NET .
Comme Json n’est que des chaînes, il est facile à manipuler si nous pouvons le manipuler correctement, quelle que soit la complexité de la structure. Je ne pense pas qu'il soit nécessaire d'utiliser une bibliothèque externe ou un convertisseur pour faire l'affaire. Voici un exemple où j'ai analysé des données JSON à l'aide d'une manipulation de chaîne.
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
Formule dans une cellule Excel
=JSON2("{mykey:1111, mykey2:{keyinternal1:22.1,keyinternal2:22.2}, mykey3:3333}", "mykey2", "keyinternal2")
AFFICHAGES: 22.2
=JSON("{mykey:1111,mykey2:2222,mykey3:3333}", "mykey2")
AFFICHAGES: 2222
Outils -> Références -> 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
En utilisant les fonctionnalités JavaScript d’analyse JSON, en plus de ScriptControl, nous pouvons créer un analyseur syntaxique en VBA qui répertoriera chaque point de données à l’intérieur du JSON. Quelle que soit la complexité ou l’imbrication de la structure de données, dans la mesure où nous fournissons un JSON valide, cet analyseur renvoie une structure arborescente complète.
Les méthodes JavaScript Eval, getKeys et getProperty fournissent des blocs de construction pour la validation et la lecture de JSON.
Couplé à une fonction récursive dans VBA, nous pouvons parcourir toutes les clés (jusqu'au nième niveau) d'une chaîne JSON. Ensuite, à l'aide d'un contrôle Tree (utilisé dans cet article), d'un dictionnaire ou même d'une simple feuille de calcul, nous pouvons organiser les données JSON selon les besoins.
Code VBA complet ici. À l'aide des fonctionnalités JavaScript de l'analyse JSON, en plus de ScriptControl, nous pouvons créer un analyseur syntaxique dans VBA qui répertoriera chaque point de données à l'intérieur du JSON. Quelle que soit la complexité ou l’imbrication de la structure de données, dans la mesure où nous fournissons un JSON valide, cet analyseur renvoie une structure arborescente complète.
Les méthodes JavaScript Eval, getKeys et getProperty fournissent des blocs de construction pour la validation et la lecture de JSON.
Couplé à une fonction récursive dans VBA, nous pouvons parcourir toutes les clés (jusqu'au nième niveau) d'une chaîne JSON. Ensuite, en utilisant un contrôle Tree (utilisé dans cet article), un dictionnaire ou même une simple feuille de calcul, nous pouvons organiser les données JSON selon les besoins.
ceci est un exemple de code vb6, testé ok, fonctionne
à partir des bons exemples ci-dessus, j'ai apporté des modifications et obtenu ce bon résultat
il peut lire les clés {} et les tableaux []
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