В Excel VBA в Windows, как смягчить проблему точечного синтаксического анализа проанализированного JSON, нарушенного поведением заглавных букв в среде IDE?
В Excel VBA в Windows, как смягчить проблему точечного синтаксического обхода анализируемого JSON, нарушенного поведением заглавных букв в среде IDE?
Привет, отвечая на мой вопрос здесь. Я проделал некоторую работу с 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 фактически можно использовать точечный синтаксис для обхода структуры JSON, но, к сожалению, это нарушается "полезностью" среды IDE VBA в отношении капитализации.
Ниже приведен пример кода, где в строке обозначено 1: мы можем видеть текст "objJSON.key1", и этот код работает до тех пор, пока не будет раскомментирован
'Tools->References->
'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx
Option Explicit
Option Private Module
Private Sub TestJSONParsingWithVBACallByName()
Dim oScriptEngine As ScriptControl
Set oScriptEngine = New ScriptControl
oScriptEngine.Language = "JScript"
Dim sJsonString As String
sJsonString = "{'key1': 'value1' ,'key2': { 'key3': 'value3' } }"
Dim objJSON As Object
Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
1: Debug.Assert objJSON.key1 = "value1"
Debug.Assert objJSON.key2.key3 = "value3"
'**** BUT IF UNCOMMENT NEXT LINE THIS AFFECTS ALL CAPITALISATION INSTANCES OF KEY1 INCLUDING LINE 1 WHICH THENCE BREAKS
2: 'Dim Key1 as Long
End Sub
Вот скриншот перед И после раскомментирования строки 2 строка 1 перезаписывается символом "key1", теперь с большой буквы "K".
Теперь после некоторых экспериментов кажется, что эффект перезаписи ограничен рамками проекта, поэтому другие проекты не затрагиваются. Это означает, что можно изолировать проблему, всегда используя отдельный проект, но затем, как можно было бы маршалировать объект до потребляющего проекта и, следовательно, получить к нему доступ, несомненно, снова возникнет та же проблема. Таким образом, изоляция проекта на самом деле не является решением.
Один из способов - убедиться, что символы не конфликтуют, и дать ключам JSON какой-то префикс, так что вот пример
'Tools->References->
'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx
Private Sub TestJSONParsingWithDotSyntaxAndKeyPrefixesToAvoidNameClash()
Dim oScriptEngine As ScriptControl
Set oScriptEngine = New ScriptControl
oScriptEngine.Language = "JScript"
Dim sJsonString As String
sJsonString = "{'kKey1': 'value1' ,'kKey2': { 'kKey3': 'value3' } }"
Dim objJSON As Object
Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
1: Debug.Assert objJSON.kKey1 = "value1"
Debug.Assert objJSON.kKey2.kKey3 = "value3"
'**** SAFE TO UNCOMMENT AS SYMBOLS DO NOT CLASH NOW
2: 'Dim Key1 As Long
End Sub
Почему-то мне это не нравится, кажется странным менять JSON только для того, чтобы VBA мог получить к нему доступ. Кроме того, может не быть контроля над исходным JSON.
Существуют и другие методы, такие как добавление некоторого javscript в обработчик сценариев, чтобы Javascript мог осуществлять доступ. Со шляпой для пользователя Codo Codo вот пример, основанный на этом подходе...
'Tools->References->
'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx
Private Sub TestJSONParsingWithMiniScript()
'hat tip to Codo https://stackoverflow.com/users/413337/codo
'Based on https://stackru.com/questions/5773683/excel-vba-parsed-json-object-loop#7300963
Dim oScriptEngine As ScriptControl
Set oScriptEngine = New ScriptControl
oScriptEngine.Language = "JScript"
oScriptEngine.AddCode "function getProperty(jsonObj, propertyName) { return jsonObj[propertyName]; } "
Dim sJsonString As String
sJsonString = "{'key1': 'value1' ,'key2': { 'key3': 'value3' } }"
Dim objJSON As Object
Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
Debug.Assert oScriptEngine.Run("getProperty", objJSON, "key1") = "value1"
Debug.Assert oScriptEngine.Run("getProperty", oScriptEngine.Run("getProperty", objJSON, "key2"), "key3") = "value3"
End Sub
Мне нравится техника добавления сценария в обработчик сценариев, однако я обнаружил более родную технику, которая заключается в использовании VBA.CallByName, и эта техника показана в моем ответе.
Я не выбрал свой собственный ответ как окончательный, потому что я думаю, что (1) кажется, что сообщество может продолжать улучшать наши знания по синтаксическому анализу JSON в Excel VBA и (2), если кто-то узнает, как остановить использование заглавных букв, тогда это очевидный победитель.
Это вопрос 1 из серии 5. Вот полная серия
Q2 В Excel VBA в Windows, как пройти через анализируемый массив JSON?
Q5 В Excel VBA в Windows, для проанализированных переменных JSON, что это за JScriptTypeInfo?
1 ответ
В конце я прогрессировал со следующим, который использует родной VBA.CallByName
'Tools->References->
'Microsoft Script Control 1.0; {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx
Private Sub TestJSONParsingWithCallByName()
Dim oScriptEngine As ScriptControl
Set oScriptEngine = New ScriptControl
oScriptEngine.Language = "JScript"
Dim sJsonString As String
sJsonString = "{'key1': 'value1' ,'key2': { 'key3': 'value3' } }"
Dim objJSON As Object
Set objJSON = oScriptEngine.Eval("(" + sJsonString + ")")
Debug.Assert VBA.CallByName(objJSON, "key1", VbGet) = "value1"
Debug.Assert VBA.CallByName(VBA.CallByName(objJSON, "key2", VbGet), "key3", VbGet) = "value3"
End Sub