VBA动态填充嵌套数据结构

时间:2020-03-01 00:00:17

标签: vba dictionary multidimensional-array collections nested

我有一些SQL表,有些是链接的,我想查询一次并本地存储在一个变量中。我无法提前预测数据的长度,因此需要动态数据结构。

我要查询的示例数据:

表1

NameA
Red
Green
Blue

表2

NameA   NameB
Red     A
Red     B
Red     C
Blue    D
Blue    E
Green   F

表3

NameA   NameC
Red     One
Blue    Two
Blue    Three
Blue    Four
Blue    Five
Green   Six
Green   Seven

我需要能够基于NameA值过滤和访问NameB和NameC。我希望使用嵌套的字典结构来查询,如下所示:

Table1("0") 'will equal "Red"
Table2("Red")("0") 'will equal "A"
Table2("Blue")("1") 'will equal "E"
Table3("Green")("1") 'will equal "Seven"
'note: point here is data structure, not order of results

我尝试使用VBA的嵌套字典,但是无法解决缺少“深度复制”功能的问题。我写的一种算法:

With SqlQueryResult
    i = 0
    Do Until .EOF
        Call Table1.Add(CStr(i), .Fields(0).Value)
        i = i + 1
        .MoveNext
    Loop
End With

For Each key In Table1.Keys
    SqlQueryResult = GetResultsFromQuery(SELECT NameB WHERE NameA = Table1(key))
    With SqlQueryResult
        i = 0
        Do Until .EOF
            Call TempDict.Add(CStr(i), .Fields(0).Value)
            i = i + 1
            .MoveNext
        Loop
    End With

    Set Table2(Table1(key)) = TempDict
    TempDict.RemoveAll
Next key

不幸的是,将一个Dict分配给另一个Dict只能设置一个引用,而实际上并不能复制数据-当我删除TempDict时,Table2中的嵌套数据也将被删除。

在嵌套结构中,每个“分支”也没有新的字典,因为我需要这些数据在模块级范围内可用,因此需要在程序执行之前在模块顶部定义这些数据。

我看过多维动态数组-无法将它们分配给像字典这样的父结构。我也无法预测每个表格的大小,例如表1的大小可能是5/20/100 / etc,表2的红色可能有2/5/100 / etcetc结果,表2的蓝色可能有1/20 / etcetc结果,Redim仅适用于数组中的单个维度。

我也对集合进行了简要介绍,但我不确定这些集合是否可行。

我对类没有太多的经验,我宁愿避免一个非常复杂的过程-我希望它易于添加链接且有所不同(即链接到表1的数据,如表2和表3,而不是标准表)将来我需要将此数据与该程序无关)。 (我对“ easy”的基准是python中的pandas数据框)。

1 个答案:

答案 0 :(得分:1)

一个简单的包装类,用于编写字典脚本,实现了一个clone方法。这应该适用于原始数据类型。

Option Explicit

Private Type State

    Dict                               As scripting.Dictionary

End Type



Private s                              As State

Private Sub Class_Initialize()

    Set s.Dict = New scripting.Dictionary

End Sub


Public Function Clone()

    Dim myClone As scripting.Dictionary
    Set myClone = New scripting.Dictionary

    Dim myKey As Variant
    For Each myKey In s.Dict

        myClone.Add myKey, s.Dict.Item(myKey)

    Next

    Set Clone = myClone

End Function


Public Property Get Item(ByVal Key As Variant) As Variant
    Item = s.Dict.Item(Key)
End Property

Public Property Set Item(ByVal Key As Variant, ByVal Value As Variant)
    s.Dict.Item(Key) = Value
End Property


Public Sub Add(ByVal Key As Variant, ByVal Item As Variant)
    s.Dict.Add Key, Item
End Sub

您现在可以说

Set Table2.Item(Table1.Item(key)) = TempDict.Clone
相关问题