且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当用作字典中的关键字时,范围的奇怪行为

更新时间:2023-09-01 15:40:40

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

So here, we have three different values being passed around:


  1. 原始范围。

  2. Range.Value ,这是一个变体。

  3. 字典内部的(1)副本。

  1. The original range.
  2. Range.Value, which is a variant.
  3. The copy of (1) which is internal to the dictionary.

如果将这些与等号相比较,都是一样的但是根据 Dictionary.Exists 他们是所有不同。

If you compare these with equal signs, they are all the same. But according to Dictionary.Exists they are all different.

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

Why? When you use an equal sign with an object, the equal sign forces the object to call its default property. The default property of Range is Range.Value, which is why r = r.Value and also r = r.Offset(0, 0).

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

But for a dictionary this isn't so smart. Think about it: Every call to Dictionary.Exists would cause every object used as a key to call its default property. This can get really expensive and it can potentially trigger a lot of side effects. So instead, Dictionary.Exists tests the following:


  1. 您是否比较一个对象到非对象?自动失败。

  2. 您是否比较两个非目标?返回 a = b

  3. 您是否比较两个对象?返回 a是b

  1. Are you comparing an object to a non-object? Automatic fail.
  2. Are you comparing two non-ojects? Return a = b.
  3. Are you comparing two objects? Return a Is b.

所以 r r.Value 不同,因为一个是一个对象,另一个是非对象。如果您使用 r 副本,就像 r.Offset(0,0),那些也不一样,因为它们仍然指向两个不同的对象,即使对象具有相同的内容。

So r is not the same as r.Value, since one is an object and the other is a non-object. And if you make a copy of r, like with r.Offset(0, 0), those are not the same either since they still point to two different objects, even if the objects have identical contents.

另一方面, >将工作,因为您将 r 转换为相同的对象 d.Keys(0)

This, on the other hand, will work, since you will make r into the same object as 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)