首页 文章

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

提问于
浏览
1

我正在尝试在vba中创建字典结构字典

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

产品编号|客户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 回答

  • 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 分支内部仍然是程序范围的本地,而 it's not an executable statement that runs when the Else branch runs .

    拆分声明和引用分配,你将修复你的错误 .

相关问题