3

我有以下代码:

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属性返回 a variant,而rngMyRange(1)is rngMyRange.item(1),它是 a range。但是,强制转换rngMyRange(1)Variant给出相同的结果..

此外,添加键是按值(因此副本rngMyRange(1)作为键传递)。但我仍然不明白为什么.Exists找不到钥匙..

先感谢您!

4

3 回答 3

3

所以在这里,我们传递了三个不同的值:

  1. 原始范围。
  2. Range.Value,这是一个变体。
  3. 字典内部的 (1) 的副本。

如果将它们与等号进行比较,它们都是相同的。但根据Dictionary.Exists他们都是不同的。

为什么?当您对对象使用等号时,等号会强制对象调用其默认属性。的默认属性RangeRange.Value,这就是为什么r = r.Value也是r = r.Offset(0, 0)

但是对于字典来说,这不是那么聪明。想一想:每次调用Dictionary.Exists都会导致每个用作键的对象调用其默认属性。这可能会变得非常昂贵,并且可能会引发很多副作用。因此,Dictionary.Exists请测试以下内容:

  1. 您是否将对象与非对象进行比较?自动失败。
  2. 你在比较两个非对象吗?返回a = b
  3. 你在比较两个对象吗?返回a Is b

Sor与 不同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)
于 2013-05-24T21:12:25.573 回答
1

我认为您的情况的原因是rngMyRange被识别为二​​维数组,并且两个数组维度都传递给您的字典。

如果您将添加元素到 Dictionary 的行更改为这一行:

dicMyHash.Add Key:=rngMyRange(1).value, Item:=0

它开始按您的预期工作 - 两个检查点都返回true

Locals Window您还可以在调试代码时分析这种情况。

于 2013-05-24T20:30:28.380 回答
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是您将 a 分配RangeKey. 如果您将范围分配给字典的项目,对我来说会更有意义。

于 2013-05-24T20:50:58.857 回答