在Windows上的Excel VBA中,對於已解析的JSON變量,此JScriptTypeInfo到底是什麼?



(1)

一個可能的地方是ScriptControl的類型庫,因為這是散發此類型的庫。

我的機器上此類型的完整詳細信息是

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

同時使用VBA IDE的對象瀏覽器和反彙編類型庫的OLEVIEW.exe,我無法跟踪接口JScriptTypeInfo或方法hasOwnProperty。

但是腳本引擎託管的語言實現不是這種情況,例如VBScript和JScript(Java的Microsoft名稱)。
所以也許我們應該尋找一個JScript實現DLL,的確有一個細節。

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

我機器上的哪個未註冊,因此不在我的“工具”->“參考”庫列表或OLEVIEW.exe中。 我很幸運能在閒逛時找到。
這是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();
};

上面的代碼顯示hasOwnProperty是IDispatch接口(或dispinterface)的一種方法,可用於處理聲明為Object類型的VBA對象(例如,將 Dim foo as Object )。使用regsvr32註冊類型庫似乎無濟於事。 必須在“工具參考”中瀏覽該文件才能在VBA的對象瀏覽器中查看。

我們可以很確定地知道這個JScript.dll文件,因為使用Process Explorer我們可以看到在執行 oScriptEngine.Language = "JScript" 正在加載的dll。在缺少註冊類型庫的情況下,我將文件JScript.dll加載到Notepad ++中並蒐索.JScriptTypeInfo作為正則表達式,並找到了匹配項。 答對了!

不僅有一個ObjectInstance描述了VBA程序遇到的大多數變量,而且還有一個引人入勝的ArrayInstance,也許我們可以使用Javascript自己的數組函數,或者至少使用JScript.dll類型庫中記錄的子集。 這是一些示例代碼

'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

簡介:JScriptTypeInfo是要在VBA IDE監視窗口中顯示的內容以及VBA函數TypeName()的返回,但實際上隱藏了許多可以在JScript.dll中找到的對象。
我想可以將其描述為多態的,也許最好將其描述為後期綁定。 要查看功能,請使用“工具參考”並瀏覽到JScript.dll。

在這裡回答我自己的問題。
我已經在Excel VBA中使用JSON完成了一些工作,並發布了許多發現,並以問答格式 https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/

因此,在stackoverflow上的其他地方,可以看到有關在VBA中解析JSON的問題,但它們似乎錯過了一兩個技巧。

首先,我不再使用自定義JSON解析庫,而是使用ScriptControl的Eval方法作為所有JSON代碼的基礎。 另外,我們對本機Microsoft解決方案表示偏愛。

這是一個先前的問題, 在Windows上的Excel VBA中,如何減輕IDE的大寫行為破壞解析的JSON的點語法遍歷的問題? 這個問題基於此。 它顯示了與使用點語法遍歷已解析的JSON對象相比,使用VBA.CallByName的魯棒性更高。 還有另一個先前的問題, 在Windows上的Excel VBA中,如何遍歷解析的JSON數組? 顯示瞭如何將其也用於訪問數組元素。 但是CallByName返回一個奇怪的變量類型,它在監視窗口中顯示為Object / JScriptTypeInfo,如果一種類型的Debug.Print在直接窗口中(或將鼠標懸停在變量上)將獲得無意義的“ [object Object]”。 在 Windows上的Excel VBA 系列中的另一個問題中 ,如何為解析的JSON變量獲取字符串化的JSON表示形式而不是“ [object Object]”? 我介紹了一些調試“糖”,它可以很好地檢查變量。 第四個問題, 在Windows Excel VBA中,如何獲取JSON密鑰以搶占“運行時錯誤'438':對像不支持此屬性或方法”? ,在研究如何查詢成員的JSON對象時,我發現了似乎附加在JScriptTypeInfo對像上的hasOwnProperty()方法。

所以我問這個問題,這個JScriptTypeInfo到底是什麼?

這是系列5的問題5。這是完整系列

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到底是什麼?





vba