将范围分配给数组时显式和隐式使用 ActiveSheet

Explicit and implicit use of ActiveSheet when assigning a range to an array

在考虑@Crouzilles 问题时: 我意识到 ActiveWorkbook.ActiveSheet 是否明确用于定义范围很重要。例如:

Dim arr1() As Variant
Dim arr2() As Variant

arr1 = Range("A1:B2")
arr2 = ActiveWorkbook.ActiveSheet.Range("A1:B2")               'Type mismatch

我假设右手边都是 return 一个 Range 对象,这将被转换成一个变体数组;但是,第二行生成类型不匹配错误:

Run-time error '13': Type mismatch

为了确保这两个语句确实 return 我检查了一个数组 TypeName():

Debug.Print TypeName(Range("A1:B2"))                            'Range
Debug.Print TypeName(ActiveWorkbook.ActiveSheet.Range("A1:B2")) 'Range

我还检查了 Range("A1:B1").Worksheet.Name 属性 以确保 Range("A1:B2") 确实是对 ActiveWorkbook.ActiveSheet.references

的引用

然后我尝试将 Range().Value 分配给两个变体的数组,这些变体正确执行:

arr1 = Range("A1:B2").Value
arr2 = ActiveWorkbook.ActiveSheet.Range("A1:B2").Value          'No error

这是有道理的,因为 .ValueRange 对象转换为变体数组....与 arr1arr2:[=32 的类型相同=]

Debug.Print TypeName(Range("A1:B2").Value)                      'Variant()
Debug.Print TypeName(ActiveWorkbook.ActiveSheet.Range("A1:B2").Value)   'Variant()

更让我困惑的是,将两个变体显式分配给 Range 引用允许分配两个数组:

Dim rng1 As Range
Dim rng2 As Range

Set rng1 = Range("A1:B2")
Set rng2 = ActiveWorkbook.ActiveSheet.Range("A1:B2")

arr1 = rng1
arr2 = rng2                                                     'No error

谁能解释为什么 Range("A1:B2") 引用的 Range 对象可以隐式转换为变体数组,而 ActiveWorkbook.ActiveSheet.Range("A1:B2") 不能?

这与绑定和默认属性的使用有关。 Activesheet return 是一个对象,而不是 Worksheet 所以之后的所有内容都是后期绑定的,而 Range(...) 实际上是 shorthand 对 Application.Range 所以它是早绑定。如果您声明一个工作表变量并将 ActiveSheet 分配给它,代码也可以工作:

Dim ws As Worksheet
Set ws = ActiveWorkbook.ActiveSheet
arr2 = ws.Range("A1:B2") ' works

将变量声明为 Variant 而不是 Variant() 也可以。

故事的寓意:始终明确属性您的意思!

来自 VBA 语言规范:

5.6.2.3 默认成员递归限制

如果 returned 对象有更多默认成员,则对其默认 属性 Get 或默认函数 return 另一个对象的对象求值可能会导致递归求值过程。如果评估为简单数据值且每个默认成员都有一个空参数列表,则通过此默认成员链的递归可能是隐式的,或者如果指定了专门参数化每个默认成员的索引表达式,则可能是显式的。

实现可以定义这种递归默认成员评估何时有效的限制。限制可能取决于诸如递归深度、空参数列表的隐式与显式规范、成员 return 特定 类 与 returning 对象或变体等因素,是否默认成员是函数与 属性 获取,以及表达式是否出现在赋值的左侧。 该实现可能会静态地确定此类评估无效,或者可能会在运行时评估期间引发错误 9(下标超出范围)或 13(类型不匹配)