В 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. Вот полная серия
Q2 В Excel VBA в Windows, как пройти через анализируемый массив JSON?
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.