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

时间:2013-11-18 19:19:35

标签: excel vba excel-vba

考虑excel中的以下vba宏

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

结果是:行1 "A1:J1", "A4:J4", "A10:J10" ,单元格"A2" 错误。 我希望单元格"A4" 。 " A2"不在uRng;为什么会被uRng.Cells(2,1)退回?

其他奇怪之处:uRng.Rows.Count = 1uRng.Columns.Count = 10。我错误地认为uRng是3x10范围?或者是未定义,因为未指定aRngbRngcRng彼此的位置?

2 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:4)

A uRng.Cells(2, 1)仅适用于连续范围而非非连续范围。要选择特定区域中的单元格,您必须处理该区域,然后使用.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也有一个奇怪之处,但由于所有范围都有相同数量的列,因此您没有对此进行重新设定。试试这个

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行数/列数?