Keywords: JSON parsing | Excel VBA | ScriptControl
Abstract: This paper delves into the core challenges and solutions for parsing nested JSON structures in Excel VBA. It focuses on the ScriptControl-based approach, leveraging the JScript engine for dynamic object traversal to overcome limitations in accessing JScriptTypeInfo object properties. The article details auxiliary functions for retrieving keys and property values, and contrasts the security advantages of regex parsers, including 64-bit Office compatibility and protection against malicious code. Through code examples and performance considerations, it provides a comprehensive, practical guide for developers.
Core Challenges of JSON Parsing in VBA
When handling JSON data in Excel VBA, developers often encounter difficulties with nested object parsing and dynamic structure access. Traditional libraries like VBJSON or vba-json may cause stack overflow due to recursion depth limits, while JScriptTypeInfo objects store complete structural information but cannot be traversed directly via VBA. This necessitates more robust methods for dynamically retrieving keys and values.
ScriptControl-Based Solution
Using Microsoft Script Control 1.0, we bridge VBA with JSON objects via the JScript engine. After initializing the script engine, add helper functions to access dynamic properties:
Option Explicit
Private ScriptEngine As ScriptControl
Public Sub InitScriptEngine()
Set ScriptEngine = New ScriptControl
ScriptEngine.Language = "JScript"
ScriptEngine.AddCode "function getProperty(jsonObj, propertyName) { return jsonObj[propertyName]; } "
ScriptEngine.AddCode "function getKeys(jsonObj) { var keys = new Array(); for (var i in jsonObj) { keys.push(i); } return keys; } "
End SubConvert JSON strings to JScriptTypeInfo objects with the DecodeJsonString function, then use GetKeys to obtain all key names:
Public Function GetKeys(ByVal JsonObject As Object) As String()
Dim Length As Integer
Dim KeysArray() As String
Dim KeysObject As Object
Dim Index As Integer
Dim Key As Variant
Set KeysObject = ScriptEngine.Run("getKeys", JsonObject)
Length = GetProperty(KeysObject, "length")
ReDim KeysArray(Length - 1)
Index = 0
For Each Key In KeysObject
KeysArray(Index) = Key
Index = Index + 1
Next
GetKeys = KeysArray
End FunctionThis method is efficient and supports nested objects, but note the early binding requirement and the need to call InitScriptEngine for initialization.
Security and Compatibility Considerations
While the ScriptControl solution is fast and effective, it poses security risks, such as allowing malicious JavaScript to access system resources via ActiveX. For example, a JSON string might contain code to create files: {a:(function(){(new ActiveXObject('Scripting.FileSystemObject')).CreateTextFile('C:\Test.txt')})()}. This highlights the need for caution when parsing untrusted data.
For 64-bit Office environments where ScriptControl is unavailable, regex parsers become the preferred choice. They use dictionaries for objects and arrays for arrays, providing methods like .Count and .Exists(), and avoid security vulnerabilities:
Sub ParseJson(ByVal strContent As String, varJson As Variant, strState As String)
Dim objTokens As Object
Dim objRegEx As Object
Dim bMatched As Boolean
Set objTokens = CreateObject("Scripting.Dictionary")
Set objRegEx = CreateObject("VBScript.RegExp")
With objRegEx
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = """(?:\\""|[^""])*""(?=\s*(?:,|\:|\]|\}))"
Tokenize objTokens, objRegEx, strContent, bMatched, "str"
' Additional pattern matching...
End With
End SubThis approach also supports beautified output and file handling, enhancing practicality.
Performance and Best Practices
In practice, the ScriptControl solution is suitable for quick parsing of trusted data, while regex parsers offer better security and cross-platform compatibility. Developers should choose based on data source and Office version. For dynamic traversal, use the GetProperty function to avoid VBA dot notation limitations, and ensure error handling for invalid JSON.
By combining these methods, VBA developers can efficiently and securely handle complex JSON structures, improving data integration capabilities.