我认为现有的答案应该可以涵盖您,但我想添加一些与您的问题相关的有用信息。
首先,语法Range(Cells(R1,C1), Cells(R2,C2))
是指从行号和列号的交集定义的单元格开始的正方形范围,直到行号和列号的交集定义的单元格(假设是,否则反之) .R1
C1
R2
C2
R1 <= R2
因此,表达式Range(Cells(LastRowP + 2, 10), Cells(LastRowP + 2, 10))
和Cells(LastRowP+2,10)
是相同的:它们都引用位于行号LastRowP+2
(无论是什么)和列号的交集处的单元格10
。这就是您的代码无法按预期工作的原因。
话虽如此,有两个重要元素被认为是不好的做法(从您对 t.thielemans 的评论看来,您似乎已经发现了一个:))。
使用选择
宏记录器使用Select
很多,它使人们很容易深入研究宏的词。但是,宏记录器不知道您的意图是什么,并试图愚蠢地复制任何动作。
s有什么问题Selection
?首先,aSelection
返回用户选择的任何内容。它可以是范围、图表、工作表或其他任何内容……这使得它变得缓慢且容易出错。如果没有选择,宏将失败,给出运行时错误。它也较慢,但对于大多数宏来说,这不是一个大问题。
通常,无需选择范围或激活工作表即可操作数据。我发现有必要激活单元格的唯一情况是需要以编程方式向单元格添加注释。Sid 上面提到的链接显示了一些在不选择/激活东西(对象)的情况下操作数据的好方法。
限定范围对象
我假设VBA
开发人员很少使用类似的语法
Range(Cells(FirstRowP + 1, 9), Cells(LastRowP + 1, 9))
我自己从不使用它..这段代码正在寻找麻烦:)
Range
和Cells
(and also Columns
or Rows
etc) 都是快捷方式。当上面的代码放在 a 中VBA module
时,它被解释为此时恰好被激活的工作表的Range
and 。Cells
换句话说,编译器理解Range = ActiveSheet.Range
和Cells = ActiveSheet.Cells
. Range("A1")
当从附加到工作表的某些东西(例如按钮)中调用时,类似的代码可能会“正常”工作,因为这ActiveSheet
将是Sheet
我们引用的那个。如果宏激活另一个工作表然后尝试引用它仍然会引起麻烦初始工作表的范围(这就是为什么它可能会“正常”工作)。当从快捷键、用户窗体等调用时,它会导致错误。
更令人困惑的是,如果将完全相同的代码放在工作表模块中,则Range
并且Cells
被解释为属于该工作表。这有多酷?:)
为了避免这样的问题,我个人对所有对象进行了限定。一个例外是当范围是时Named
(例如检查here),那么我们可以参考它就好了(除非我们在下面的情况下!)。
现在,资格的微妙之处在工作簿中延续。所以Sheet1.Range("A1")
暗示ActiveWorkbook.Sheet1.Range("A1")
。如果我们激活不同的工作簿,Sheet1.Range("A1")
将引用该工作簿的范围。如果不同工作簿的两个命名范围具有相同的名称,那么我们也需要对它们进行限定。
总而言之,避免Select
离子和完全限定的对象将使您免于许多错误和麻烦。
我希望这有帮助!