В Excel VBA в Windows, для проанализированных переменных JSON, что это за JScriptTypeInfo?

Отвечая на мой собственный вопрос здесь.
Я проделал некоторую работу с JSON в Excel VBA и много выводов, которые я опубликую, которые я сделаю в формате вопросов и ответов https://stackru.com/help/self-answer http://blog.stackru.com/2011 / 07 / его нормально-к-аск-ответ-своего собственного вопросы /

Так что в другом месте на stackru можно увидеть вопросы о разборе JSON в VBA, но они, кажется, пропускают хитрость или два.

Для начала я отказываюсь от использования пользовательских библиотек анализа JSON и вместо этого использую метод ScriptControl Eval как основу всего моего кода JSON. А также мы выражаем предпочтение родным решениям Microsoft.

Вот предыдущий вопрос В Excel VBA на Windows, как уменьшить проблему точечного синтаксического анализа синтаксического анализа JSON, нарушенного поведением заглавных букв в среде IDE? на котором строится этот вопрос. Он показывает, что использование VBA.CallByName более надежно, чем использование точечного синтаксиса для прохождения проанализированного объекта JSON. Также еще один предыдущий вопрос В Excel VBA на Windows, как пройти через анализируемый массив JSON? показывает, как его также можно использовать для доступа к элементам массива. Но CallByName возвращает любопытный тип переменной, который появляется в окне Watch как Object/JScriptTypeInfo, и если один тип Debug.Print в непосредственном окне (или наводит курсор на переменную), он получает неинформативный "[object Object]". Другой вопрос из серии В Excel VBA для Windows, как получить строковое представление JSON вместо "[объект объекта]" для проанализированных переменных JSON? Я представляю некоторый отладочный "сахар", который позволяет хорошо проверить переменные. В четвертом вопросе Как в Windows Excel VBA получить ключи JSON с предупреждением "Ошибка времени выполнения" 438 ": объект не поддерживает это свойство или метод"? исследуя, как запросить объект JSON для члена, я обнаружил метод hasOwnProperty (), который кажется прикрепленным к объекту JScriptTypeInfo.

Итак, в этом вопросе я спрашиваю, что это за JScriptTypeInfo?

Это вопрос 5 серии 5. Вот полная серия

В1. В Excel VBA в Windows, как уменьшить проблему точечного синтаксического анализа синтаксического анализа JSON, нарушенного поведением заглавных букв в среде IDE?

Q2 В Excel VBA в Windows, как пройти через анализируемый массив JSON?

Q3 В Excel VBA в Windows, как получить строковое представление JSON вместо "[объектный объект]" для проанализированных переменных JSON?

Q4 В Windows Excel VBA, как получить ключи JSON для предупреждения "Ошибка времени выполнения" 438 ": объект не поддерживает это свойство или метод"?

Q5 В Excel VBA в Windows, для проанализированных переменных 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 

Используя как Object Browser VBA IDE, так и OLEVIEW.exe, который разбирает библиотеку типов, я не могу проследить интерфейс JScriptTypeInfo или метод hasOwnProperty.

Но разве это не тот случай, когда механизм сценариев содержит языковые реализации, такие как VBScript и JScript (имя Microsoft для Javascript).
Так что, возможно, нам следует искать DLL-библиотеку реализации JScript, и здесь есть одна деталь.

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

который на моей машине не зарегистрирован, и поэтому не в моем списке библиотек Tools->References или в 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), необходимого для работы с объявленным объектом VBA типа Object (например, Dim foo as Object) Регистрация библиотеки типов с помощью regsvr32 ничего не делает. Для просмотра в браузере объектов VBA необходимо перейти к файлу в разделе "Ссылки на инструменты".

Мы можем быть уверены в этом файле JScript.dll, потому что, используя Process Explorer, мы можем видеть, что dll загружается при выполнении строки oScriptEngine.Language = "JScript"В отсутствие зарегистрированной библиотеки типов я загрузил файл 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.
Я полагаю, это можно описать как полиморфное, возможно, лучше описать его как позднее связывание. Для просмотра возможностей используйте Tools-References и перейдите к JScript.dll.

Другие вопросы по тегам