在这里回答我自己的问题.
我已经在Excel VBA中使用JSON做了一些工作,并发布了许多调查结果,我将以问答形式发布这些内容
https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011/07/ITS-OK-到问一答,你自己的问题/
所以在stackoverflow的其他地方,人们可以看到有关在VBA中解析JSON的问题,但他们似乎错过了一两个技巧.
首先,我重新使用自定义JSON解析库,而是使用ScriptControl的Eval方法作为我所有JSON代码的基础.此外,我们还表达了本机Microsoft解决方案的偏好.
这是一个先前的问题在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题?这个问题的基础.它显示了使用VBA.CallByName比使用点语法遍历解析的JSON对象更强大.另一个先前的问题在Windows上的Excel VBA中,如何循环解析JSON数组?展示了如何使用它来访问数组元素.但是CallByName返回一个奇怪的变量类型,它在Watch窗口中显示为Object/JScriptTypeInfo,如果在一个窗口中有一个类型Debug.Print(或悬停在变量上),则会得到无信息的"[object Object]".
我们如何改进并获得JSON字符串表示?
以下是您在Debug.Print(?)之后在立即窗口中看到的内容以及将鼠标悬停在变量上的屏幕截图.
这是5系列的问题3.这是完整系列
Q1 在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题?
Q2 在Windows上的Excel VBA中,如何循环解析JSON数组?
Q3 在Windows上的Excel VBA中,如何为已解析的JSON变量获取字符串化的JSON表示而不是"[object Object]"?
Q4 在Windows Excel VBA中,如何获取JSON键以抢占"运行时错误'438':对象不支持此属性或方法"?
Q5 在Windows上的Excel VBA中,对于已解析的JSON变量,这个JScriptTypeInfo究竟是什么?
与使用已解析的JSON对象相关的其他堆栈溢出问题的答案使用小型脚本方法,我们可以在此处使用此方法。
首先,我们承认Douglas Crockford是“ Javascript:The Good Parts”(http://shop.oreilly.com/product/9780596517748.do)的作者,并且是javascript专家。因此,我们很高兴采用他关于字符串化的代码。我们可以通过一个简单的Xml HTTP Request(通常简称为XHR)来获取他的代码,并将返回结果传递给ScriptControl的AddCode方法。然后添加一些代码,使我们能够通过调用Douglas的库来覆盖“ [object Object]”的默认表示。然后确保我们动态地将该覆盖值添加到所有JScriptTypeInfo变量中,这些变量既是我们用DecodeJsonString()包装的ScriptControl的Eval方法产生的,还是我们用GetJSONObject()包装的VBA.CallByName产生的。
从而,
'Tools->References->
'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx
'Microsoft Xml, v6.0
Option Explicit
Private Function GetScriptEngine() As ScriptControl
Static soScriptEngine As ScriptControl
If soScriptEngine Is Nothing Then
Set soScriptEngine = New ScriptControl
soScriptEngine.Language = "JScript"
soScriptEngine.AddCode GetJavaScriptLibrary("https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js")
soScriptEngine.AddCode "function overrideToString(jsonObj) { jsonObj.toString = function() { return JSON.stringify(this); } }"
End If
Set GetScriptEngine = soScriptEngine
End Function
Private Function GetJavaScriptLibrary(ByVal sURL As String) As String
Dim xHTTPRequest As MSXML2.XMLHTTP60
Set xHTTPRequest = New MSXML2.XMLHTTP60
xHTTPRequest.Open "GET", sURL, False
xHTTPRequest.send
GetJavaScriptLibrary = xHTTPRequest.responseText
End Function
Private Function DecodeJsonString(ByVal JsonString As String) As Object
Dim oScriptEngine As ScriptControl
Set oScriptEngine = GetScriptEngine
Set DecodeJsonString = oScriptEngine.Eval("(" + JsonString + ")")
Call oScriptEngine.Run("overrideToString", DecodeJsonString) '* this gives JSON rendering instead of "[object Object]"
End Function
Private Function GetJSONObject(ByVal obj As Object, ByVal sKey As String) As Object
Dim objReturn As Object
Set objReturn = VBA.CallByName(obj, sKey, VbGet)
Call GetScriptEngine.Run("overrideToString", objReturn) '* this gives JSON rendering instead of "[object Object]"
Set GetJSONObject = objReturn
End Function
Private Sub TestJSONParsingWithCallByName2()
Dim sJsonString As String
sJsonString = "{'key1': 'value1' ,'key2': { 'key3': 'value3' } }"
Dim objJSON As Object
Set objJSON = DecodeJsonString(sJsonString)
Stop
Dim objKey2 As Object
Set objKey2 = GetJSONObject(objJSON, "key2")
Debug.Print objKey2
Stop
End Sub
Run Code Online (Sandbox Code Playgroud)
这是新代码的屏幕截图,显示了JScriptTypeInfo变量的字符串化