简体   繁体   English

在Windows Excel VBA中,将JSON写入2d变量数组

[英]In Windows Excel VBA, writing JSON to a 2d variant array

Answering my own question here. 在这里回答我自己的问题。 It is possible to call into JavaScript running in the Microsoft Script Control and return some JSON data structure. 可以调用在Microsoft脚本控件中运行的JavaScript并返回一些JSON数据结构。 Whilst it is possible to parse the JSON with the Evaluate method of the script control, sometimes one wants to write to a two dimensional (2d) variant array which can then be pasted directly to a sheet or return in a user defined function. 尽管可以使用脚本控件的Evaluate方法解析JSON,但有时可能要写入二维(2d)变体数组,然后可以将其直接粘贴到工作表或返回用户定义的函数。 This bumps up against marshalling of data structures. 这与数据结构的编组冲突。

One cannot pass a 2d variant array into a JavaScript function, write to it and then pass it back. 无法将2d变体数组传递给JavaScript函数,无法对其进行写入然后再传递回。 [If you have proof that is untrue please post]. [如果您有不正确的证据,请发表]。 So this code fails 所以这段代码失败了

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONtoOleVariantGridFails1()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    oScriptEngine.AddCode "function WriteResults1(vGrid) { vGrid(0,0)=1.2;vGrid(0,1)='red';vGrid(1,0)=true;vGrid(1,1)=null; return vGrid;};"

    ReDim vGridBefore(0 To 1, 0 To 1)
    Dim vGridAfter
    vGridAfter = oScriptEngine.Run("WriteResults1", vGridBefore) '<---- FAILS with error "Cannot assign to a function result"

    Debug.Assert vGridAfter(0, 0) = 1.2
    Debug.Assert vGridAfter(0, 1) = "red"
    Debug.Assert vGridAfter(1, 0) = True
    Debug.Assert IsNull(vGridAfter(1, 1))


End Sub

So this begs the question how best to populate a 2d variant array? 因此,这就引出了一个问题:如何最好地填充2d变量数组?

I have a solution which I'm posting but I'd be fascinated to know if someone else has figured out the marshalling between JSON and 2d variant arrays. 我有一个要发布的解决方案,但是我很着迷于是否有人发现了JSON和2d变体数组之间的编组。

Here is my solution which works by creating a class to wrap the 2d variant array and then passing in a reference to the class. 这是我的解决方案,它的工作方式是创建一个包装2d变量数组的类,然后将对该类的引用传递给它。 This is like "boxing". 这就像“拳击”。

'Tools->References->
'Microsoft Script Control 1.0;  {0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}; C:\Windows\SysWOW64\msscript.ocx

Private Sub TestJSONtoOleVariantGridSucceeds()

    Dim oScriptEngine As ScriptControl
    Set oScriptEngine = New ScriptControl
    oScriptEngine.Language = "JScript"

    oScriptEngine.AddCode "function WriteResults(oGrid) { oGrid.Redimension(2,2); oGrid.Cell(0,0)=1.2;oGrid.Cell(0,1)='red';oGrid.Cell(1,0)=true;oGrid.Cell(1,1)=null;};"

    Dim oGrid As JSONOLEVariant
    Set oGrid = New JSONOLEVariant

    Call oScriptEngine.Run("WriteResults", oGrid)

    Dim vGrid As Variant
    vGrid = oGrid.ExportGridData

    Debug.Assert vGrid(0, 0) = 1.2
    Debug.Assert vGrid(0, 1) = "red"
    Debug.Assert vGrid(1, 0) = True
    Debug.Assert IsNull(vGrid(1, 1))



End Sub

and the class code JSONOLEVariant.cls 和类代码JSONOLEVariant.cls

Option Explicit
Option Base 0

Private mvGridData As Variant

Public Function ExportGridData()
    ExportGridData = mvGridData
End Function

Public Sub Redimension(ByVal lRows As Long, ByVal lColumns As Long)
    ReDim mvGridData(0 To lRows - 1, 0 To lColumns - 1) 'Zero base
End Sub

Public Property Let Cell(ByVal lRow As Long, ByVal lColumn As Long, ByVal vNewValue As Variant)
    mvGridData(lRow, lColumn) = vNewValue
End Property

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM