2016-06-30 41 views
1

我試圖創建字典結構的字典中VBA嵌套的字典:錯誤457:此鍵已與收集

基本的元素相關聯,我開始用3列的表:

產品ID |客戶ID |來源

1 | 1 | A

1 | 2 | A

2 | 1 | A

3 | 1 | B

我想將它轉換成主字典「DicByUser」,其中鍵是用戶標識符,而項目是另一個字典,它包含作爲客戶端訪問的產品和源代碼的項目的鍵。

在這種情況下,我會

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

我的方法是經過我的初始表中的所有行,則:

與熙德的客戶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中?

編輯:通過改變我的代碼如下解決,由墊的馬克杯

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 
+2

似乎暗淡新的未使用後正確釋放,嘗試手動釋放它(設置dicotoadd =無),並嘗試從分裂聲明instatiation(外部光線變暗,如果,然後設置dictotoadd =新的Scripting.Dictionary) – tsolina

回答

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分支內不會改變它的範圍,它仍然LO CAL到過程的範圍,它不是在else分支運行運行的可執行語句。

拆分的聲明和引用賦值,你會解決你的bug。