我正在使用以下VBA代码(MS Excel 2010)来选择给定范围内的一系列单元格,以将复制的单元格复制并插入到源范围中: 范围从第2行的工作表开始,一直到第2200行,第50行到第65行。
Set rngFEA = shtTarget.range("myrange")
iMaxLines = 20
With rngFEA
.Range(Cells(3, 1), Cells(3 + iMaxLines, .Columns.Count)).Copy
.Range(Cells(3, 1), Cells(3 + iMaxLines, .Columns.Count)).Insert Shift:=xlDown
End With
这样做(没有为单元格(行,列)参数引用rngFEA)工作正常,所选单元格是预期范围的一部分。
我不喜欢不使用cell()参数的引用,因为不使用引用会使单元格引用工作表而是产生错误的结果,所以我更愿意使用rngFEA.cells():
Set rngFEA = shtTarget.range("myrange")
iMaxLines = 20
With rngFEA
.Range(.Cells(3, 1), .Cells(3 + iMaxLines, .Columns.Count)).Copy
.Range(.Cells(3, 1), .Cells(3 + iMaxLines, .Columns.Count)).Insert Shift:=xlDown
End With
但是结果范围远远超出范围rngFEA,在某个地方向左和向下。 我甚至找不到使用的索引和结果偏移之间的关系。
我相信range.insert也可以表示为
rngFEA.cells(3,1).insert shift:=xldown
但这不是我现在关注的问题。
我很清楚引用与否的区别,但我不明白为什么不使用范围的引用会得到正确的结果,并且使用引用不会。
我希望
rngFEA.range(rngFEA.cells(1,1), rngFEA.cells(10,10))
将给定范围的最顶部,最左边的单元格的范围向下返回到右边的第十个单元格,然后向下返回相同的范围。 在示例代码中,我在给定范围内选择第3行中最左边的单元格,直到第23个单元格和范围的右端。 (实际选择的行是工作簿中的第3行,因此范围中的第2行) 我查看了微软信息和几个论坛,但找不到足以描述这种效果的解释。
我知道
range.row
返回范围开始的WORKSHEET中的行号
range.column
返回范围开始的列。
选择给定范围内的单元格或行
range.row(2)
不会返回范围的第二行,而是返回工作表的第二行。甲
for each myrow in range.rows
索引
myrow.row
返回范围内的行号,但是使用它作为选择索引似乎返回工作表中的行,所以我需要添加
range.row + myrow.row
索引到范围内的实际行。
这背后的机制以及选择范围内的上述行为让我感到困惑。 由于有许多方法可以使用VBA处理Excel中的内容,我希望您能给我一个解释所描述行为的一般解释而不是解决方案(如果不是为了解释原因):)
提前THXYdalir
答案 0 :(得分:5)
可以确认此行为:
Sub Tester()
Dim rng As Range
Set rng = Range("C3:H28")
'This selects E5:F6 (???)
With rng
.Range(.Cells(1, 1), .Cells(2, 2)).Select
End With
'This selects C3:D4 (expected)
With rng
rng.Parent.Range(.Cells(1, 1), .Cells(2, 2)).Select
End With
End Sub
似乎它可能与"双亲相关"同时使用.Range
和.Cells
相反使用rng.Parent.Range
并且只有.Cells
相对于包含范围似乎可以修复它(并且仍然允许完全限定范围引用)
答案 1 :(得分:2)
在VB.Net中获取某个范围内的Excel范围时遇到了相同的行为。 Tim's answer解决了这种奇怪的行为。起初我虽然它与使用With
有关,但我想这与Tim建议的点符号的双重相对引用有关。
Public Sub SomeMergingFunction(ByRef inputRange As Excel.Range)
With inputRange
Debug.Print(.Address) ' $A$4:$A$130 correct
Debug.Print(.Cells(1, 1).Address) ' $A$4 correct
Debug.Print(.Range(.Cells(1, 1), .Cells(1, 1)).Address) ' $A$7 wrong
Debug.Print(.Parent.Range(.Cells(1, 1), .Cells(1, 1)).Address) ' $A$4 correct
End With
End Sub