非连续范围内的范围,单元格(和项目)

时间:2015-10-08 11:43:28

标签: vba excel-vba excel

我正在查看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

3 个答案:

答案 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$1Intersect(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