select一个范围内的范围

我正在使用下面的VBA代码(MS Excel 2010)来select给定范围内的单元格范围,以将复制的单元格复制并插入到源范围中:范围从工作表的第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)工作正常,所选单元格是预期范围的一部分。

我不喜欢使用没有参考cells()参数,因为使用没有引用使单元格引用工作表,而是给出错误的结果,所以我宁愿使用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)) 

将给定范围的最顶端的最左边单元格的范围向下返回到第十个单元格,并在同一范围内向右和向下。 在示例代码中,我select在给定范围内的第3行中的最左边的单元格,直到第23个单元格和该范围的右端。 (实际select的行是工作簿中的第3行,因此是范围中的第2行)我查看了微软信息和几个论坛,但找不到足以描述这种效果的解释。

我知道

 range.row 

返回范围开始的WORKSHEET中的行号,

 range.column 

返回范围开始的列。

select给定范围内的单元格或行

 range.row(2) 

不会返回范围的第二行,而是工作表的第二行。 一个

 for each myrow in range.rows 

该指数

 myrow.row 

返回范围内的行数,但将其用作select索引似乎返回工作表内的行,所以我需要添加

 range.row + myrow.row 

索引到范围内的实际行。

背后的机制和上述select一个范围内的范围的行为是令我困惑的。 由于在Excel中使用VBA有很多方法来处理事情,所以我希望你能给我一个所描述行为的一般解释,而不是一个解决scheme(如果不是解释为什么):)

THX提前

Ydalir

可以确认这一行为:

 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相对于包含范围似乎可以解决它(并且仍然允许完全限定范围引用)

在VB.Net中获取范围内的Excel范围时,我遇到了相同的行为。 蒂姆的答案解决了怪异的行为。 起初,我认为这与使用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