Excel VBA – 范围联盟及其子范围

在excel中考虑下面的vbamacros

Sub foo() Dim aRng As Range: Set aRng = ActiveSheet.Range("A1:J1") Dim bRng As Range: Set bRng = ActiveSheet.Range("A4:J4") Dim cRng As Range: Set cRng = ActiveSheet.Range("A10:J10") Dim uRng As Range: Set uRng = Union(aRng, bRng, cRng) uRng.Style = "Good" uRng.Cells(2, 1).Style = "Bad" End sub 

结果是:行"A1:J1", "A4:J4", "A10:J10" 良好 ,单元格"A2" 不好 。 我预计电池"A4"坏的 。 “A2”不在uRng ; 为什么它会被uRng.Cells(2,1)返回?

其他古怪: uRng.Rows.Count = 1uRng.Columns.Count = 10 。 我期望uRng是3×10范围吗? 或者是不确定的,因为aRngbRngcRng彼此的位置没有被规定?

它们实际上被视为三个独立的范围,可以通过Range.Areas属性从uRng访问:

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.areas(v=office.11​​).ASPX

使用你的例子,下面是如何获得A4 ,作为第二个范围的第一个单元格:

 Sub foo() Dim aRng As Range: Set aRng = ActiveSheet.Range("A1:J1") Dim bRng As Range: Set bRng = ActiveSheet.Range("A4:J4") Dim cRng As Range: Set cRng = ActiveSheet.Range("A10:J10") Dim uRng As Range: Set uRng = Union(aRng, bRng, cRng) uRng.Style = "Good" uRng.Areas(2).Cells(1, 1).Style = "Bad" End Sub 

另外,下面的代码会给你同样的结果:

 Sub foo2() Dim uRng As Range: Set uRng = [A1:J1,A4:J4,A10:J10] uRng.Style = "Good" uRng.Areas(2).Cells(1, 1).Style = "Bad" End Sub 

uRng.Cells(2, 1)仅适用于连续范围而不是非连续范围。 要select特定区域的单元格,必须先寻址该区域,然后使用.Cells(r,w)

例如

 uRng.Areas(n).Cells(r, c) 

其中n是要写入的区域, rc是行/列。

B. Rows.Count与1区域一起使用。 因此,要查找行数在非连续范围内,您将不得不循环。

看到这个例子

 Option Explicit Sub foo() Dim aRng As Range: Set aRng = ActiveSheet.Range("A1:J1") Dim bRng As Range: Set bRng = ActiveSheet.Range("A4:J4") Dim cRng As Range: Set cRng = ActiveSheet.Range("A10:J10") Dim rngArea As Range Dim rwCount As Long Dim uRng As Range: Set uRng = Union(aRng, bRng, cRng) If uRng.Areas.Count > 1 Then Debug.Print "It's a non-contiguous range" For Each rngArea In uRng.Areas rwCount = rwCount + rngArea.Rows.Count Next Debug.Print "The range has " & rwCount & " rows" Else Debug.Print "It's a contiguous range" Debug.Print "The range has " & uRng.Rows.Count & " rows" End If End Sub 

C.columns.count有一个奇怪的情况,但是由于所有的范围都有相同的列数,所以你没有把它重新expression出来。 尝试这个

 Option Explicit Sub foo() Dim aRng As Range: Set aRng = ActiveSheet.Range("A1:J1") Dim bRng As Range: Set bRng = ActiveSheet.Range("A4:K4") '<~~ I changed this. Dim cRng As Range: Set cRng = ActiveSheet.Range("A10:J10") Dim uRng As Range: Set uRng = Union(aRng, bRng, cRng) '~~> This will still give you 10 instead of `11` Debug.Print uRng.Columns.Count End Sub 

所以同样的逻辑也适用于查找列的数量。

IMP :现在取决于你想如何计算行数/列数。 如果区域的行/列重叠呢? 在这种情况下,你想要在这个非连续的范围内的行/列或实际的Excel行/列的总数?