VBA中的嵌套字典:错误457:此键已与集合元素关联

时间:2016-06-30 16:09:33

标签: excel vba dictionary

我试图在vba中创建字典结构字典

基本上,我从3列表开始:

产品ID |客户ID |源

1 | 1 |甲

1 | 2 |甲

2 | 1 |甲

3 | 1 |乙

我想把它变成一本主词典" DicByUser"其中键是用户ID,而项是另一个字典,其中包含客户端访问的产品和源代码作为项的键。

在那种情况下,我会

DicByUser = {1:{1:A,2:A,3:B},2:{1:A}}

我的方法是遍历我的初始表的所有行:

使用Cid客户ID,

Pid产品ID,

获取来源

If DicByUser.Exists(Cid) Then
    If DicByUser.Item(Cid).Exists(Pid) Then
        'We do something on the item
    Else
        DicByUser.Item(Cid).Add Pid, source
    End If
 Else
    Dim dicotoadd As New Scripting.Dictionary
    dicotoadd.Add Pid, source
    DicByUser.Add Cid, dicotoadd

奇怪的是,最后一行给我的错误是:vba告诉我

Error 457 : this key is already associated with an element of collection

然后,如果我进入调试模式并尝试显示对象dicotoadd中的元素数量,我会找到1,而对象是在之前的行创建的。

我相信我将字典放在另一个字典中的方式可能有问题,总是给它一个相同的名字,否则我不明白为什么我在上面创建一行的字典已经包含了一个元素

我在vba中创建嵌套字典的过程中做错了什么?

编辑:解决方法是将我的代码更改为以下内容,如Mat的Mug所示

If DicByUser.Exists(Cid) Then
    If DicByUser.Item(Cid).Exists(Pid) Then
        'We do something on the item
    Else
        DicByUser.Item(Cid).Add Pid, source
    End If
 Else
    Dim dicotoadd As Scripting.Dictionary
    Set dicotoadd = New Scripting.Dictionary
    dicotoadd.Add Pid, source
    DicByUser.Add Cid, dicotoadd

1 个答案:

答案 0 :(得分:2)

经典陷阱。

  • VBA中变量的最小范围是过程级
  • 程序范围内的
  • As New会更改对象的生命周期

这是一个应该启发你的简单例子:

Public Sub DoSomething()

    Dim c1 As New Collection 'notice: As New
    c1.Add "TEST"
    Set c1 = Nothing
    c1.Add "this will NOT throw runtime error 91"

    Dim c2 As Collection
    Set c2 = New Collection
    c2.Add "TEST"
    Set c2 = Nothing
    c2.Add "this WILL throw runtime error 91"

End Sub

您的代码声明DicByUser As New - 它在Else分支内的事实并没有改变其范围,它仍然是程序范围的本地,并且它不是在Else分支运行时运行的可执行语句

拆分声明和引用分配,您将修复您的错误。