VBA 更新/修改多重嵌套字典中的数组

Ala*_*ana 1 arrays excel vba dictionary nested

以下是完整的 VBA 代码。我创建了一个多重嵌套字典,其键结构为team>> 。这些值将存储为数组,以便我可以使用 访问这些值。membermthmydict(team)(member)(mth)(0 or 1)

但是,当我通过循环字典键并声明一个临时数组来修改数组元素来更新数组时。它没有走正确的路。

完整的 VBA 代码

Sub test()

Dim mydict1 As New Scripting.Dictionary
Dim mydict2 As New Scripting.Dictionary
Dim mydict3 As New Scripting.Dictionary
Dim mydict4 As New Scripting.Dictionary

For Each mth In Array(1, 2)
    mydict3.Add mth, Array("NA", "NA")
Next mth

For Each member In Array(11, 22, 33)
    mydict4.Add member, mydict3
Next member

For Each team In Array(1, 2)
mydict1.Add team, mydict4
Next team

i = 1

For Each team In mydict1.Keys()
    For Each member In mydict1(team).Keys()
        For Each mth In mydict1(team)(member).Keys()

                Dim tmparr As Variant

                tmparr = mydict1(team)(member)(mth)
                tmparr(0) = i
                mydict1(team)(member)(mth) = tmparr
                Debug.Print mth & "---" & team & "---" & member & "---" & Join(mydict1(team)(member)(mth), "---")
                i = i + 1
            
        Next mth
    Next member
Next team


Debug.Print "================================================='"

For Each team In mydict1.Keys()
    For Each member In mydict1(team).Keys()
        For Each mth In mydict1(team)(member).Keys()
                Debug.Print mth & "---" & team & "---" & member & "---" & Join(mydict1(team)(member)(mth), "---")
        Next mth
    Next member
Next team

End Sub

Run Code Online (Sandbox Code Playgroud)

输出

1---1---11---11---NA
2---1---11---12---NA
1---1---22---11---NA
2---1---22---12---NA
1---1---33---11---NA
2---1---33---12---NA
1---2---11---11---NA
2---2---11---12---NA
1---2---22---11---NA
2---2---22---12---NA
1---2---33---11---NA
2---2---33---12---NA
Run Code Online (Sandbox Code Playgroud)

预期产出

1---1---11---1---NA
2---1---11---2---NA
1---1---22---3---NA
2---1---22---4---NA
1---1---33---5---NA
2---1---33---6---NA
1---2---11---7---NA
2---2---11---8---NA
1---2---22---9---NA
2---2---22---10---NA
1---2---33---11---NA
2---2---33---12---NA
Run Code Online (Sandbox Code Playgroud)

Fun*_*mas 5

您需要区分 VBA 中的数组和对象。与其他编程语言不同,VBA 不将数组作为对象处理。

这意味着如果你写

mydict3.Add mth, Array("NA", "NA")
Run Code Online (Sandbox Code Playgroud)

VBA 将首先创建一个包含 2 个字符串变量(“NA”、“NA”)的数组,然后在将其作为值分配给字典时创建该数组的副本。同样,当您从字典中读取数组时,VBA 会将数组复制tmpArr到变量 中。如果您随后修改该数组,则需要将其写回字典条目(这将再次创建一个副本)。你已经这样做了:

 tmparr = mydict1(team)(member)(mth)    ' Copy the array to tmp variable
 tmparr(0) = i                          ' Modify the array
 mydict1(team)(member)(mth) = tmparr    ' Write the modification back to the dict
Run Code Online (Sandbox Code Playgroud)

如果您编写mydict1(team)(member)(mth)(0) = i,则存储在字典中的数组不会被修改,因为这里首先创建了一个副本。这常常会导致混乱,并且这里有几个问题。

对象不同。当你写的时候

mydict4.Add member, mydict3
Run Code Online (Sandbox Code Playgroud)

存储的值是对字典的引用myDict3。中的所有条目myDict4将指向完全相同的对象myDict3,如果修改myDict3,它将影响的所有条目myDict4

所以你要做的就是myDict3在填充时创建一个新的Dictionary对象,并且在填充时myDict4你需要创建一个新的Dictionary对象。myDict4myDict1

看看下面的代码。由于我发现您的命名非常混乱,因此我可以自由地重命名字典对象:

Dim teamDict As Scripting.Dictionary
Dim mthDict As Scripting.Dictionary
Dim memberDict As Scripting.Dictionary

Set teamDict = New Dictionary
Dim team
For Each team In Array(1, 2)
    Set memberDict = New Dictionary
    Dim member
    For Each member In Array(11, 22, 33)
        Set mthDict = New Dictionary
        Dim mth
        For Each mth In Array(1, 2)
            mthDict.Add mth, Array("NA", "NA")
        Next mth
        memberDict.Add member, mthDict
    Next member
    teamDict.Add team, memberDict
Next team
Run Code Online (Sandbox Code Playgroud)

  • 托马斯,您将干货转化为真正有用的*乐趣* - 您在哪里可以真正获得如此好的咖啡机作为支持工具? (2认同)