我正在查看Holene问题exportAntProperties
,在尝试理解MSDN文档时遇到了以下问题。有人可以解释为什么以下几行给出两种不同的结果吗?
Sub test()
Debug.Print "With Cells(2)"
Debug.Print Intersect(Range("B:B, C:C"), Rows(1)).Cells(2).Address 'prints $C$1
Debug.Print Intersect(Range("B:B, D:D"), Rows(1)).Cells(2).Address 'prints $B$2
Debug.Print Range("B:B, C:C").Cells(2).Address 'prints $B$2
Debug.Print Range("B:B, D:D").Cells(2).Address 'prints $B$2
Debug.Print "With Item(2)"
Debug.Print Intersect(Range("B:B, C:C"), Rows(1)).Item(2).Address 'prints $C$1
Debug.Print Intersect(Range("B:B, D:D"), Rows(1)).Item(2).Address 'prints $B$2
Debug.Print Range("B:B, C:C").Item(2).Address 'prints $B$2
Debug.Print Range("B:B, D:D").Item(2).Address 'prints $B$2
End Sub
答案 0 :(得分:2)
如果您不向Cells
提供行索引和列索引,它将从指定范围的第一个区域从左到右,从上到下迭代。
如果您传递的索引大于该范围内的单元格数,则继续使用该模式,根据原始范围中的列数限制遍历的区域。
所以如果你使用:
Range("A1:C1").Cells(3).address
你得到$ C $ 1。如果你传递4作为索引,它会循环到下一行,你得到$ A $ 2.
请注意,如果超过第一个区域的整列中的可用单元格数,则会出现错误。所以:
Range("A1").Cells(rows.Count).address
将返回$ 1048576澳元,但如果您使用:
Range("A1").Cells(rows.Count + 1).address
您收到错误而不是$ B $ 1,因为范围仅限于第一个区域的宽度和工作表的高度(即整个A列)。
答案 1 :(得分:2)
许多VBA Range方法在连续范围内完美运行,但在范围有多个区域时具有特殊行为,即它们适用于范围的第一个区域。单元格(i)是其中之一,但是当在For Each cell in myRange
排序中跨越范围时,它们将正常工作并跨越所有单元格,即使范围有多个区域。
在测试的第一行,Intersect方法返回了一个连续的范围B1:C1,所以第2项自然是C1。因为带有一个参数的单元格(i)从左到右逐行跨越该区域。
在第二行中,Intersect方法返回了一个多区域范围:(B1,D1)。所以Cell(i)仅适用于第一个区域,即B1。
ps:Range.Cells()虽然以这种方式工作,但不会检查返回的单元格是否属于原始范围。
编辑:回答第三行
在第三行中,(B:B,C:C)的定义是多区域范围,第一区域是行B,第二区域是行C.对于人类来说,这相当于(B: C),但不适用于编译器。当定义范围时,编译器不会尝试合并区域,因为这种操作在计算上是密集的并且在一般情况下是困难的。它只是在定义范围时不会尝试自动合并区域,它遵循程序员的定义。我更喜欢它:遵循程序员的逻辑并保持快速。
答案 2 :(得分:1)
Intersect(Range("B:B, C:C"), Rows(1))
给出了连续范围$B$1:$C$1
。
Intersect(Range("B:B, D:D"), Rows(1))
给出了一个不连续的范围$B$1,$D$1
。
连续范围只有一个Area
。非连续的不止一个。
如果您指的是范围的单元格而没有明确说明哪个是Area
,那么默认情况下您将获得第一个区域。
$B$1:$C$1
的第一个区域是$B$1:$C$1
,其中第二个区域是$C$1
。
$B$1,$D$1
的第一个区域是$B$1
,其中第二个区域是(离开区域的边界!)$B$2
。