当您选择一个打开了相对引用的范围时,宏记录器会做两件事:
- 它确定与将成为新选择范围左上角单元格的活动单元格的偏移量。如果您从 A1 转到 B1,它将构建
ActiveCell.Offset(0,1)
为向下移动零行,向右移动一列。
- 它确定新选择的范围的宽度和高度,并以 A1 表示法构建高度和宽度的命令。如果从 A1 到 B1,它会计算出新的范围为 1x1。在 A1 表示法中,相对于活动单元格的 1x1 选择是“A1”,因此它继续构建命令为
ActiveCell.Offset(0,1).Range("A1")
他们必须构建宏记录器以分两步执行此操作,因为您可以选择多个单元格。如果您从 A1 转到 B1:C7。你得到
ActiveCell.FormulaR1C1 = "First Cell"
ActiveCell.Offset(0, 1).Range("A1:B7").Select
这意味着“从活动单元格右侧的零行和一列的单元格开始,然后就好像它是整个工作表的左上角单元格一样,选择一个两列宽和七个单元格高的范围。
令人困惑的部分是 A1 符号。人们只会想到像 A1 这样的单元格引用来引用整个工作表。所以像 C6 这样的引用将始终是第三列和第六行。
但在 VBA 中,您可以从任何单元格开始使用 A1 表示法。您可以选择单元格 K10,然后在立即窗口中输入:
?activecell.Range("b2").Range("b2").Range("b2").Address
你会得到 13 美元。这些 B2 引用中的每一个都意味着向右移动一列并向下移动一行。他们三个连续做三次。关键是它以一个Range
对象开头,即ActiveCell
。如果您从工作表开始,例如Sheet1
or ActiveSheet
,那么 A1 表示法将相对于工作表的左上角。
为什么没有它就可以工作?
Range("A1")
如果您选择一个单元格,它仅在没有该部分的情况下才有效。如果您选择了多个单元格,您仍然可以删除 Range 部分,但代码将无法正常工作。
它在没有 Range 部分的情况下工作的另一个重要原因是该Offset
属性返回一个Range
对象。有很多属性可以返回Range
对象,包括Range
、Offset
、Resize
和Cells
. 任何返回Range
对象的属性都可以跟.Select
因为Select
是Range
对象的属性。
为什么记录仪包含单个单元格?
除了创建宏记录器的程序员之外,没有人知道。他们可以很容易地计算出新选择的范围是单个单元格并在 处停止ActiveCell.Offset(0,1).Select
,但无论新选择的高度和宽度如何,执行这两个步骤可能更容易。