范围对象 – 为什么有时候我不能使用纸张

在这个线程中:

Excel VBA在特定工作表的范围内查找最大值

我发现范围对象有一个奇怪的行为。 我真的不能把手指放在这个问题上,这更像是一种感觉。 有时候,你不应该在范围对象前加一个表格,有时你可以。 对我来说,这感觉很明显,但我不能真正解释它。 任何人都可以澄清呢?

这工作:

Range(Cells(1, 1), Cells(2, 2)).Value = "X" 

这感觉真的很糟糕,但它的工作原理:

 Sheets(2).Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(2, 2)).Value = "X" 

这些不起作用:

 Sheets(1).Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(2, 2)).Value = "X" Sheets(1).Range("Sheet2!A1:B2").Value = "X" 

我可以将所有单元格(1,1)对象更改为范围(“a1”),结果将是相同的。

我最好的猜测是,只要传递给Range对象的参数定义了特定工作表上的单元格,就不能在提到的范围之前定义工作表。 但是,如果不是这种情况,则允许您使用表单对象在范围之前。

我认为这里的关键是Range对象可以是applicationworksheet对象的子对象。

正如约翰·科尔曼在他的回答中所写的:

Microsoft文档明确指出:“使用时没有对象限定符,此属性[Range]是ActiveSheet.Range的快捷方式”

实际上,如果你认为“对象限定符”不是Range对象的父对象,但它也可以在它内部( sheets(n)Range(Sheets(n).cells(y,x))的对象限定符Range(Sheets(n).cells(y,x)) ),所以可能的情况是:

  • Sheets(n).range(cells(y,x))是有效的并且指的是Sheets(n)
  • Sheets(n).range(Sheets(n).cells(y,x))也是有效的并且表示Sheets(n)
  • Range(Sheets(n).cells(y,x))也是有效的,并且指的是仍然在Sheets(n)Range – 这里Range的父亲不是活动activesheet ,而是application对象!
  • Range(cells(y,x))是有效的并且指的是ActiveSheet的范围
  • Sheets(k).range(Sheets(n).cells(y,x))无效,因为父Sheets(k)不包含Sheets(n)中的单元格Sheets(n)

这似乎有点倒退。 你总是可以在一个Range之前放一个明确的Sheet ,但有时你不需要。 Range Excel对象模型中WorkSheet对象的子项。 VBA有一个默认对象的概念,它允许你有时保持父对象的隐式。 在Range的情况下,默认的父对象是ActiveSheet 。 如果您要在活动工作表上指定一个范围,那么您可以直接引用该范围,但是如果您正在尝试引用另一个工作表上的范围,则需要提供明确的工作表参考。 你的两个例子没有意义,因为你试图通过引用另一个表单上的范围来构build一个表单的范围。 这就好像说你想要在纽约和波士顿之间的德国部分。

编辑:vacip发现了一个明显的exception。 Microsoft文档明确指出:“如果在没有对象限定符的情况下使用,则此属性[ Range ]是ActiveSheet.Range的快捷方式”因此,在下面的代码块中,如果在Sheet 1处于活动状态时运行,则两行应相同首先是第二个“捷径”:

 Sub test() Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(2, 2)).Value = 1 ActiveSheet.Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(2, 2)).Value = 1 End Sub 

但实际情况是,第一条线成功地改变了一个不活动的纸上的范围,但是第二条线失败了。 奇。

看来VBA正在对不合格的对象进行假设,这可能不是你所假设的。 通常,一个不合格的Range对象将引用活动表单。 但是,如果范围对象是不合格的,并且包含的​​Cells参数是合格的,则范围对象将由Cells.Worksheet对象限定。

总是最好的资格。 例如:

 With Sheets(2) .Range(.Cells(1, 1), .Cells(2, 2)).Value = "X" End With 

尽pipe以下内容也适用:

 With Sheets(2) Range(.Cells(1, 1), .Cells(2, 2)).Value = "X" End With