2012-01-02 57 views
1

下面的代碼摘自一個較大的過程(周圍的代碼是不相關的)。任何人都可以解釋爲什麼我無法獲得第二個ContainsKey行來返回True?提示:在只有少數填充單元格的工作表上試試這一點,以減少循環。Vb.Net使用字典與Excel範圍作爲鍵

 For Each ws As Excel.Worksheet In Wb.Worksheets 
      Dim dic As New Dictionary(Of Excel.Range, String) 
      rngUsed = ws.UsedRange 
      For Each cell As Excel.Range In rngUsed 
       dic.Add(cell, "test") 
       'THE FOLLOWING TWO MESSAGES SHOULD DISPLAY THE SAME RESULT, BUT DO NOT. WHY??? 
       MsgBox(dic.ContainsKey(cell)) 'Returns True 
       MsgBox(dic.ContainsKey(ws.Range(cell.Address))) 'Returns False 
      Next 
     Next 

更新:我已添加以下代碼和它似乎是工作:

Dim dic As New Dictionary(Of Excel.Range, String)(New MyComparer()) 'replaces line from above 

Class MyComparer 
Implements IEqualityComparer(Of Excel.Range) 
Public Function Equals1(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).Equals 
    If x.Address(External:=True) = y.Address(External:=True) Then 
     Return True 
    Else 
     Return False 
    End If 
End Function 
Public Function GetHashCode1(ByVal obj As Excel.Range) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).GetHashCode 
    Return obj.Count.GetHashCode 
End Function 

末級

+0

爲什麼不使用'cell.Address'作爲關鍵? – 2012-01-02 20:25:31

+0

Tim,回答你的問題,這是因爲行的插入/移除會把我的鑰匙搞砸。我發佈了我認爲是上述答案的東西(到目前爲止,它似乎工作正常)。 – OfficeAddinDev 2012-01-02 20:27:01

+0

@Ryan如果您對自己的解決方案感到滿意,您應該將更新轉到答案並接受它。 – 2012-01-02 20:35:11

回答

1
Dim dic As New Dictionary(Of Excel.Range, String)(New MyComparer()) 'replaces line from above 

Class MyComparer 
Implements IEqualityComparer(Of Excel.Range) 
Public Function Equals1(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).Equals 
    If x.Address(External:=True) = y.Address(External:=True) Then 
     Return True 
    Else 
     Return False 
    End If 
End Function 
Public Function GetHashCode1(ByVal obj As Excel.Range) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).GetHashCode 
    Return obj.Count.GetHashCode 
End Function 

這是解決方案。請注意,在這個自定義比較器中使用的GetHashCode非常緩慢,所以如果任何人有一個想法來加快速度,我很樂意聽到它。 @competent_tech,我必須使用對象作爲鍵,因爲對於範圍來說沒有字符串表示是唯一的並且不會改變(例如,當添加/刪除行時地址如何改變)。

1

當對象被用作密鑰的字典,.NET使用GetHashCode生成在底層散列表中使用的密鑰。由於您使用了兩個不同的對象,因此您將得到不同的值。

請參閱the MSDN documentation瞭解更多詳情。

更好的方法是將範圍轉換爲字符串表示並將其用作關鍵字。