我有以下代码:
Dim dicMyHash As Dictionary
Dim rngMyRange As Range
' A1 is empty - although the outcome is the same in any case
Set rngMyRange = Range("A1")
Set dicMyHash = New Dictionary
dicMyHash.Add Key:=rngMyRange(1), Item:=0
Debug.Print dicMyHash.Exists(rngMyRange(1).Value) ' returns False
Debug.Print rngMyRange(1) = rngMyRange(1).Value ' returns True
这种行为有些出乎意料。背景中是否有某种类型的演员? rngMyRange(1).Value
属性返回variant
,而rngMyRange(1)
是rngMyRange.item(1)
,这是range
。但是,将rngMyRange(1)
投射到Variant
会得到相同的结果。
此外,按键添加键(因此rngMyRange(1)
的副本作为键传递)。但我仍然无法理解为什么.Exists
找不到钥匙..
提前谢谢!
答案 0 :(得分:3)
所以在这里,我们传递了三个不同的值:
Range.Value
,这是一种变体。如果将它们与等号相比较,它们都是一样的。但根据Dictionary.Exists
,他们所有不同。
为什么呢?对象使用等号时,等号会强制对象调用其默认属性。 Range
的默认属性为Range.Value
,这就是r = r.Value
和r = r.Offset(0, 0)
的原因。
但对于字典来说,这并不是那么聪明。考虑一下:对Dictionary.Exists
的每次调用都会导致用作密钥的每个对象调用其默认属性。这可能会变得非常昂贵,并且可能会引发很多副作用。因此,Dictionary.Exists
测试以下内容:
a = b
。a Is b
。所以r
与r.Value
不同,因为一个是对象而另一个是非对象。如果您创建r
的副本,与r.Offset(0, 0)
一样,那些也不一样,因为它们仍指向两个不同的对象,即使这些对象具有相同的内容
另一方面,将工作,因为您将r
变为与d.Keys(0)
相同的对象:
Dim d As Scripting.Dictionary
Dim r As Range
Set r = [a1]
Set d = New Dictionary
d.Add r, 0
Set r = d.Keys(0)
Debug.Print d.Exists(r)
答案 1 :(得分:1)
我认为你的情况的原因是rngMyRange
被识别为二维数组,并且两个数组维都被传递到你的字典。
如果您将将元素添加到Dictionary中的行更改为:
dicMyHash.Add Key:=rngMyRange(1).value, Item:=0
它开始按预期工作 - 两个检查点都返回true
。
您可以在调试代码的同时在Locals Window
中分析这种情况。
答案 2 :(得分:0)
我不确定你如何使用它,但这将返回True
:
Sub test()
Dim dicMyHash As Dictionary
Dim rngMyRange As Range
Set rngMyRange = Range("A1")
Set dicMyHash = New Dictionary
dicMyHash.Add Key:=rngMyRange(1).Value, Item:=0 ' assign it with Value
Debug.Print dicMyHash.Exists(rngMyRange(1).Value)
End Sub
那么你将拥有一个带有A1中任何一个键的项目。
我认为没有Value
它无效的原因是您要为Range
分配Key
。如果你将范围分配给字典的项目,那对我来说会更有意义。