Dans Excel VBA sur Windows, pour les variables JSON parsées qu'est-ce que C'est jscripttypeinfo de toute façon?

répondant à ma propre question ici.

J'ai fait quelques travaux avec JSON dans Excel VBA et beaucoup de conclusions à poster que je vais le faire dans le format Q & A https://stackoverflow.com/help/self-answer http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions /

donc ailleurs sur stackoverflow on peut voir des questions sur l'analyse de JSON dans VBA mais ils semblent manquer une astuce ou de deux.

pour commencer, je n'utilise pas les bibliothèques d'analyse JSON personnalisées et j'utilise plutôt la méthode Eval de ScriptControl comme base de tout mon code JSON. Et nous exprimons également une préférence de Microsoft solutions natives.

Voici une question préalable dans Excel VBA sur Windows, comment atténuer la question de la syntaxe de point traversée de JSON parsemé brisée par le comportement de capitalisation D'IDE? sur laquelle cette question s'appuie. Il montre comment utiliser VBA.CallByName est plus robuste que d'utiliser la syntaxe de point pour traverser un objet JSON analysé. Aussi une autre question préalable dans Excel VBA sur Windows, comment boucler à travers un tableau JSON analysé? montre comment il peut également être utilisé pour accéder aux éléments du tableau. Mais CallByName renvoie un type de variable curieux qui apparaît dans la fenêtre Watch comme Object/JScriptTypeInfo et si un type de Débogage.D'impression dans la fenêtre (ou de la pointe sur la variable), on obtient l'imprécis "[object Objet."] Dans une autre question dans la série dans Excel VBA sur Windows, Comment obtenir une représentation JSON stringifiée au lieu de "[Objet Objet]" pour les variables JSON parsées? je présente du" sugar " de débogage qui permet un bon contrôle des variables. Dans une quatrième question dans Windows Excel VBA, comment obtenir les clés JSON pour préempter "Run-time error '438': Object doesn't support this property or method"? , tout en comment interroger un objet JSON pour un membre je découvre une méthode hasOwnProperty () qui semble attachée à un objet JScriptTypeInfo.

donc dans cette question je demande, ce qui est exactement ce JScriptTypeInfo de toute façon?

C'est la Question 5 de la série de 5. Voici la série complète

Q1 in Excel VBA on Windows, how to mitige issue of dot syntax traversal of parsed JSON broken by IDE capitalization behaviour?

Q2 dans Excel VBA sur Windows, Comment faire une boucle à travers un tableau JSON parsed?

Q3 dans Excel VBA sur Windows, Comment obtenir une représentation JSON stringifiée au lieu de "[Objet Objet]" pour les variables JSON parsées?

Q4 dans Windows Excel VBA, comment obtenir les clés JSON pour préempter "erreur D'exécution '438': objet ne supporte pas cette propriété ou méthode"?

Q5 Dans Excel VBA sur Windows, pour analysée JSON variables qu'est-ce que ce JScriptTypeInfo de toute façon?

4
demandé sur Community 2016-06-08 22:20:14

1 réponses

un endroit possible pour regarder est dans la bibliothèque de type pour le ScriptControl car c'est la bibliothèque qui émane ce type.

les détails complets de ce type sur ma machine sont

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

utilisant à la fois le navigateur objet de VBA IDE et OLEVIEW.exe qui démonte le type de bibliothèque, je peux pas trace de l'interface JScriptTypeInfo ou la méthode hasOwnProperty.

mais n'est-ce pas le cas que le moteur de script héberge implémentations de langage, telles que VBScript et JScript (nom de Microsoft pour Javascript).

Alors peut-être que nous devrions chasser pour une DLL de mise en œuvre JScript et en effet il ya un ici sont les détails

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

qui sur ma machine n'est pas enregistré et donc pas dans ma liste d'outils->bibliothèques de références ou dans OLEVIEW.EXE. J'ai eu de la chance de le trouver en fouillant.

Voici quelques résultats D'OLEVIEW donnant une exception de la type bibliothèque

[
  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();
};

ce qui précède montre que hasOwnProperty est une méthode D'interface IDispatch (ou dispinterface) nécessaire pour travailler avec un objet VBA déclaré de type (par exemple Dim foo as Object ) Enregistrer la bibliothèque de type avec regsvr32 semble ne rien faire. Il faut parcourir le fichier dans les références D'outils pour voir dans le navigateur d'objet de VBA.

nous pouvons être assez sûrs de ce JScript.fichier dll parce qu'en utilisant L'Explorateur de processus nous pouvons voir la dll étant chargée lors de l'exécution de la ligne oScriptEngine.Language = "JScript" En l'absence d'une bibliothèque de type enregistrée, j'ai chargé le fichier JScript.dll dans Notepad++ et recherché .J. S. C. R. I. p. T. T. Y. p. E. I. N. F. o comme une expression régulière et trouvé un succès. Bingo!

non seulement il y a un ObjectInstance qui décrirait la plupart des variables qu'un programme VBA rencontre, mais il y a aussi un ArrayInstance qui est intriguant, peut-être pouvons-nous utiliser les propres fonctions du tableau de Javascript ou au moins un sous-ensemble tel que décrit dans JScript.la bibliothèque de type dll. Voici un exemple de 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

résumé: JScriptTypeInfo est quelque chose à montrer dans la fenêtre VBA IDE watch et le retour de la fonction VBA TypeName() mais qui cache réellement un certain nombre d'objets qui peuvent être trouvés dans JScript.DLL.

Je suppose qu'il peut être décrit comme polymorphe, peut-être mieux de le décrire comme la liaison tardive. Pour voir les capacités utiliser des outils-références et naviguer vers JScript.DLL.

5
répondu S Meaden 2016-06-08 19:20:14