简体   繁体   English

在Windows上的Excel VBA中,对于已解析的JSON变量,这个JScriptTypeInfo究竟是什么?

[英]In Excel VBA on Windows, for parsed JSON variables what is this JScriptTypeInfo anyway?

answering my own question here. 在这里回答我自己的问题。
I have done some work with JSON in Excel VBA and lots of findings to post which I will do so in Q & A format https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ 我已经在Excel VBA中使用JSON做了一些工作,并发布了许多调查结果,我将以问答形式发布这些内容https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011 / 07 / ITS-OK-到问一答,你自己的问题/

So elsewhere on stackoverflow one can see questions about parsing JSON in VBA but they seem to miss a trick or two. 所以在stackoverflow的其他地方,人们可以看到有关在VBA中解析JSON的问题,但他们似乎错过了一两个技巧。

To begin with, I resile from using custom JSON parsing libraries and instead use the ScriptControl's Eval method as the basis of all my JSON code. 首先,我重新使用自定义JSON解析库,而是使用ScriptControl的Eval方法作为我所有JSON代码的基础。 And also we express a preference from native Microsoft solutions. 此外,我们还表达了本机Microsoft解决方案的偏好。

Here is a prior question In Excel VBA on Windows, how to mitigate issue of dot syntax traversal of parsed JSON broken by IDE's capitalisation behaviour? 这是一个先前的问题在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题? upon which this question builds. 这个问题的基础。 It shows how using VBA.CallByName is more robust than using the dot syntax to traverse a parsed JSON object. 它显示了使用VBA.CallByName比使用点语法遍历解析的JSON对象更强大。 Also another prior question In Excel VBA on Windows, how to loop through a JSON array parsed? 另一个先前的问题在Windows上的Excel VBA中,如何循环解析JSON数组? shows how it also can be used to access array elements. 展示了如何使用它来访问数组元素。 But CallByName returns a curious variable type that appears in Watch window as Object/JScriptTypeInfo and if one type Debug.Print in the immediate window (or hovers over the variable) one gets the uninformative "[object Object]". 但是CallByName返回一个奇怪的变量类型,它在Watch窗口中显示为Object / JScriptTypeInfo,如果在一个窗口中有一个类型Debug.Print(或悬停在变量上),则会得到无信息的“[object Object]”。 In another question in the series In Excel VBA on Windows, how to get stringified JSON respresentation instead of “[object Object]” for parsed JSON variables? Windows上的Excel VBA系列中的另一个问题中,如何为已解析的JSON变量获取字符串化的JSON表示而不是“[object Object]”? I present some debugging "sugar" that allows nice inspection of variables. 我提出了一些调试“糖”,可以很好地检查变量。 In a fourth question In Windows Excel VBA,how to get JSON keys to pre-empt “Run-time error '438': Object doesn't support this property or method”? 在第四个问题中在Windows Excel VBA中,如何获取JSON键以抢占“运行时错误'438':对象不支持此属性或方法”? , whilst investigating how to query a JSON object for a member I discover a hasOwnProperty() method that seems attached to a JScriptTypeInfo object. ,在研究如何查询成员的JSON对象时,我发现似乎附加到JScriptTypeInfo对象的hasOwnProperty()方法。

So in this question I ask, what exactly is this JScriptTypeInfo anyway? 所以在这个问题中我问,究竟这个JScriptTypeInfo究竟是什么?

This is Question 5 of series of 5. Here is the full series 这是5系列的问题5.这是完整系列

Q1 In Excel VBA on Windows, how to mitigate issue of dot syntax traversal of parsed JSON broken by IDE's capitalisation behaviour? Q1 在Windows上的Excel VBA中,如何减轻由IDE的大小写行为破坏的解析JSON的点语法遍历问题?

Q2 In Excel VBA on Windows, how to loop through a JSON array parsed? Q2 在Windows上的Excel VBA中,如何循环解析JSON数组?

Q3 In Excel VBA on Windows, how to get stringified JSON respresentation instead of “[object Object]” for parsed JSON variables? Q3 在Windows上的Excel VBA中,如何为已解析的JSON变量获取字符串化的JSON表示而不是“[object Object]”?

Q4 In Windows Excel VBA,how to get JSON keys to pre-empt “Run-time error '438': Object doesn't support this property or method”? Q4 在Windows Excel VBA中,如何获取JSON键以抢占“运行时错误'438':对象不支持此属性或方法”?

Q5 In Excel VBA on Windows, for parsed JSON variables what is this JScriptTypeInfo anyway? Q5 在Windows上的Excel VBA中,对于已解析的JSON变量,这个JScriptTypeInfo究竟是什么?

One possible place to look is in the type library for the ScriptControl as this is the library which emanates this type. 一个可能的地方是ScriptControl的类型库,因为这是发出此类型的库。

The full details of this type on my machine are 我机器上这种类型的完整细节是

Libary Name:    Microsoft Script Control 1.0 (Ver 1.0)       
LIBID:          {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}
Location:       C:\wINDOWS\SysWOW64\msscript.ocx 

Using both VBA IDE's Object Browser and OLEVIEW.exe which disassembles type library I can no trace of the interface JScriptTypeInfo or the method hasOwnProperty. 使用VBA IDE的对象浏览器和反汇编类型库的OLEVIEW.exe,我无法跟踪接口JScriptTypeInfo或方法hasOwnProperty。

But isn't it the case that the script engine hosts language implementations, such as VBScript and JScript (Microsoft name for Javascript). 但是脚本引擎不是主持语言实现的情况,例如VBScript和JScript(Javascript的Microsoft名称)。
So perhaps we should hunt for a JScript implementation DLL and indeed there is one here are details 所以也许我们应该寻找一个JScript实现DLL,实际上这里有一个细节

Libary Name:    Microsoft JScript Globals
LIBID:          {3EEF9759-35FC-11D1-8CE4-00C04FC2B085}
Location:       C:\wINDOWS\SysWOW64\jscript.dll 

which on my machine is not registered and so not in my list of Tools->References libraries or in OLEVIEW.exe. 我的机器上没有注册,因此不在我的Tools-> References库列表或OLEVIEW.exe中。 I was lucky to find whilst poking around. 我很幸运,一边寻找一边。
Here is some output from OLEVIEW giving an exceprt of the type library 这是OLEVIEW的一些输出,给出了类型库的异常

[
  uuid(3EEF9758-35FC-11D1-8CE4-00C04FC2B097)
]
dispinterface ObjectInstance {
    properties:
    methods:
        [id(0x0000044c)]
        StringInstance* toString();
        [id(0x0000044d)]
        StringInstance* toLocaleString();
        [id(0x0000044e)]
        VARIANT hasOwnProperty(VARIANT propertyName);
        [id(0x0000044f)]
        VARIANT propertyIsEnumerable(VARIANT propertyName);
        [id(0x00000450)]
        VARIANT isPrototypeOf(VARIANT obj);
        [id(0x00000451)]
        ObjectInstance* valueOf();
};

This above shows the hasOwnProperty to be a method of a IDispatch interface (or dispinterface) necessary to work with VBA object's declared of type Object (eg Dim foo as Object ) Registering the type library with regsvr32 appears to do nothing. 上面显示hasOwnProperty是一个IDispatch接口(或dispinterface)的方法,它必须使用VBA对象声明的Object类型(例如Dim foo as Object )使用regsvr32注册类型库似乎什么都不做。 One must browse to the file in Tools References to view in VBA's object browser. 必须浏览到工具引用中的文件才能在VBA的对象浏览器中查看。

We can be pretty sure about this JScript.dll file because using Process Explorer we can see the dll being loaded when executing the line oScriptEngine.Language = "JScript" In the lack of a registered type library I loaded the file JScript.dll into Notepad++ and searched for .JScriptTypeInfo as a regular expression and found a hit. 我们可以非常确定这个JScript.dll文件,因为使用Process Explorer我们可以看到在执行行时加载了oScriptEngine.Language = "JScript"在没有注册类型库的情况下,我将文件JScript.dll加载到Notepad ++中并搜索.JScriptTypeInfo作为正则表达式并找到了匹配。 Bingo! 答对了!

Not only is there an ObjectInstance which would describe most of the variables a VBA program encounters but also there is an ArrayInstance which is intriguing, perhaps we can use Javascript's own array functions or at least a subset as documented in JScript.dll's type library. 不仅有一个ObjectInstance可以描述VBA程序遇到的大多数变量,而且还有一个有趣的ArrayInstance,也许我们可以使用Javascript自己的数组函数或者至少是JScript.dll类型库中记录的子集。 Here is some sample code 这是一些示例代码

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

'and FYI/browsing capabilities       Microsoft JScript Globals;   C:\wINDOWS\SysWOW64\jscript.dll

Option Explicit

Private Sub TestJSONParsingWithCallByName5()

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

    Dim sJsonString(0 To 1) As String
    sJsonString(0) = "{'key1': 'value1'  ,'key2': { 'key3': 'value3' } }"
    sJsonString(1) = "[ 1234, 2345, 3456, 4567, 5678, 6789 ]"



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

    Debug.Assert objJSON(0).hasOwnProperty("key1")
    Debug.Assert objJSON(0).hasOwnProperty("key2")

    Debug.Assert CallByName(objJSON(1), "length", VbGet) = 6
    Debug.Assert CallByName(objJSON(1), "0", VbGet) = "1234"

    '* Is objJSON(1) an ArrayInstance?
    '* does it support the reverse method of the ArrayInstance object?

    'Call objJSON(1).Reverse  '* reverse gets capitalised into Reverse ... grrrr
    Call CallByName(objJSON(1), "reverse", VbMethod) '* so use CallByName as solution to "helpful" capitalisation

    '* Yes, the elements are reversed!

    Debug.Assert CallByName(objJSON(1), "length", VbGet) = 6
    Debug.Assert CallByName(objJSON(1), "0", VbGet) = "6789"

    Stop

    '** And now we know objJSON(1) is an ArrayInstance we can have some fun with array operations

    Dim objSplice As Object
    Set objSplice = CallByName(objJSON(1), "splice", VbMethod, 2, 1)
    Debug.Assert CallByName(objJSON(1), "length", VbGet) = 5
    Debug.Assert CallByName(objSplice, "length", VbGet) = 1

    Dim objSlice As Object
    Set objSlice = CallByName(objJSON(1), "slice", VbMethod, 2)
    Debug.Assert CallByName(objJSON(1), "length", VbGet) = 5
    Debug.Assert CallByName(objSlice, "length", VbGet) = 3

    Stop
    Call CallByName(objJSON(1), "sort", VbMethod)


    Debug.Assert CallByName(objJSON(1), "join", VbMethod) = "1234,2345,3456,5678,6789"
    Debug.Assert CallByName(objJSON(1), "join", VbMethod, " ") = "1234 2345 3456 5678 6789"
    Stop


    Debug.Assert CallByName(objJSON(1), "pop", VbMethod) = "6789"
    Debug.Assert CallByName(objJSON(1), "length", VbGet) = 4
    Stop
End Sub

SUMMARY: JScriptTypeInfo is something to show in the VBA IDE watch window and the return of the VBA function TypeName() but which really hides a number of objects that can be found in JScript.dll. 概要:JScriptTypeInfo是在VBA IDE监视窗口中显示的东西,以及VBA函数TypeName()的返回,但它实际上隐藏了可以在JScript.dll中找到的许多对象。
I suppose it can be described as polymorphic, perhaps better to describe it as late binding. 我认为它可以被描述为多态,也许更好地将其描述为后期绑定。 To view capabilities use Tools-References and browse to JScript.dll. 要查看功能,请使用Tools-References并浏览到JScript.dll。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM