为什么Worksheet.Cells函数的返回类型会随着赋值变量而改变?

时间:2020-08-04 15:57:46

标签: excel vba

我有以下宏代码。

Sub display_name()
    Dim strName As String
    Dim nameCell As Range
        
    strName = ActiveSheet.Cells(1, 1) 'String
    Set nameCell = ActiveSheet.Cells(1, 1) 'Range Object
    
    MsgBox "Content: " & strName & ", " & nameCell.Value
End Sub

MsgBox值:

内容:Hello world,Hello world

在第一种情况下, ActiveSheet.Cells 方法返回一个字符串,在第二行中,同一方法返回一个范围对象。

根据vba文档, Worksheet.Cells 返回范围对象。我来自Java背景,发现这种行为不合适。

我有以下问题,

  1. 为什么 Worksheet.Cells 的返回类型会因 分配给变量的类型?
  2. 为什么VBA允许这种行为?

1 个答案:

答案 0 :(得分:2)

在VBA中使用Set语句时,您正在将对象引用分配给对象变量。在大多数语言中,您没有此Set命令,而是为引用分配了=:=,但是在VBA中,您必须使用Set。 / p>

如果省略Set并尝试将对象分配给变量,则会收到运行时错误438。只有一个例外:

VBA具有默认成员的概念。每个类可能都有一个Default成员(并非所有类都有一个!)。如果您使用的对象没有指定成员,并且您没有引用该对象的引用(例如,使用Set或在期望对象时将对象作为参数传递),则VBA将隐式引用Default成员。 / p>

默认成员在多种情况下派上用场。以一个Collection为例,您可以在其中通过索引访问它的成员,就好像它是一个简单数组一样。因此,您编写MyCollection(1)来访问第一个成员-实际上,您要调用的函数Item是Collection的默认成员。

默认成员,也可能导致混乱。如果将对象作为参数传递给子例程,并且参数定义为类型Variant,则VBA会传递对象的引用或默认成员的值吗?

如果您想知道类的默认成员,请转到对象浏览器[F2],然后使用蓝色图标查找该成员。 This answer解释了它的用法-包括如何显示隐藏的成员。

基本上,Range的默认成员很复杂。但是,如果Range仅包含一个单元格,则为该单元格的Value(据我所知,它是成员Value2)。您会发现,使用默认成员经常会访问单元格的值-正如您在示例代码中所做的那样。但是我会建议您明确写出strName = ActiveSheet.Cells(1, 1).Value-不要留下任何误解的余地。

如果您对更多详细信息感兴趣,请阅读此Rubberduck article。这里是interesting Question on SO关于Range的 real 默认成员的信息。而且,如果您仍然不够困惑,请阅读this