Vba 非连续范围{非工作表搜索}中的最后一行或单元格

Vba 非连续范围{非工作表搜索}中的最后一行或单元格,vba,excel,Vba,Excel,首先,这不是典型的新手问题。我正在尝试在已正确创建的区域中查找最后一行(或单元格) 在这个例子中,我用union将两个范围合并为一个范围。在整个范围内循环,我得到了我想要的数据,一切都很顺利 Sub Test() Dim unionRange As Range, currentRow As Range Set unionRange = Union(Range("A3:C5"), Range("A8:C11")) For Each currentRow In union

首先,这不是典型的新手问题。我正在尝试在已正确创建的区域中查找最后一行(或单元格)

在这个例子中,我用union将两个范围合并为一个范围。在整个范围内循环,我得到了我想要的数据,一切都很顺利

Sub Test()

    Dim unionRange As Range, currentRow As Range
    Set unionRange = Union(Range("A3:C5"), Range("A8:C11"))

    For Each currentRow In unionRange.Rows
        Debug.Print "Row: " & currentRow.row
    Next currentRow

End Sub
这就给出了这些结果

Row: 3
Row: 4
Row: 5
Row: 8
Row: 9
Row: 10
Row: 11
但是,当我想确定当前行是否是范围内的最后一行时,我似乎找不到一个干净的方法来获取该信息

Sub Test()

    Dim unionRange As Range, currentRow As Range
    Set unionRange = Union(Range("A3:C5"), Range("A8:C11"))

    For Each currentRow In unionRange.Rows
        Dim lastRowIndex As Integer

        'lastRowIndex = unionRange. ???

        If currentRow.row = lastRowIndex Then
            MsgBox ("Last Row")
        End If

    Next currentRow

End Sub
之所以如此困难,是因为我尝试的每个解决方案都只在第一个连续组中生成信息,如下所示

    Debug.Print unionRange.Rows.Count ' 3 (should be 7)
    Debug.Print unionRange.Rows(unionRange.Rows.Count).row ' 5 (should be 11)
除了在这一行之前进行第二个循环外,还有其他方法获取最后一行的地址信息吗?

下一行是空的,这不是一定范围内的“最后”行吗?在这种情况下,应采用以下方法:

Sub Test()

Dim unionRange As Range, currentRow As Range
Set unionRange = Union(Range("A3:C5"), Range("A8:C11"))

For Each currentRow In unionRange.Rows
    Dim lastRowIndex As Integer

    If currentRow.Cells(1, 1).Offset(1, 0).Value = vbNullString Then
        MsgBox "Last Row in " & currentRow.Row
    End If

Next currentRow

End Sub
更新: 多亏了@AndASM,我今天才学到了一些新东西!!我对
区域一无所知
!因此,请不要将我的答案标记为正确答案(即使这解决了您的问题)

但是,我想提供以下代码,因为我相信这可能更符合您的要求:

Sub Test()

Dim unionRange As Range, currentRow As Range, subArea As Range
Set unionRange = Union(Range("A3:C5"), Range("A8:C11"))

For Each currentRow In unionRange.Rows
    For Each subArea In unionRange.Areas
        If Not Intersect(subArea, currentRow) Is Nothing Then
            If currentRow.Row = subArea.Row + subArea.Rows.Count - 1 Then
                MsgBox "Last Row in " & currentRow.Row
            End If
        End If
    Next subArea
Next currentRow

End Sub

您需要使用范围的Areas属性。当一个范围不连续时,它包含多个区域。每个区域都是子范围。不幸的是,区域没有以任何方式进行排序。因此,您需要检查循环中的每个区域,然后返回最大行数

在下面的示例中,我创建了一个函数,它为您提供非连续范围内的最后一行号。test sub将行号打印到Visual Basic for Applications编辑器中的即时窗口

Public Function GetLastRowOfNonContiguousArea(targetRange As Range) As Long
    Dim subRange As Range
    Dim maxRow As Long, areaMaxRow As Long

    maxRow = 0

    For Each subRange In targetRange.Areas
        areaMaxRow = subRange.Rows(subRange.Rows.Count).Row
        If areaMaxRow > maxRow Then maxRow = areaMaxRow
    Next subRange

    GetLastRowOfNonContiguousArea = maxRow
End Function

Public Sub test()
    Dim testRange As Range

    Set testRange = Union([A5:A9], [E20:F21], [C1:C3])

    Debug.Print GetLastRowOfNonContiguousArea(testRange)
End Sub

不,OP指定了非连续,然后通过他们的示例说明了他们的意思是非连续啊,我曾尝试使用区域的,但我没有意识到它们没有排序!我一定是选错了测试用的。不过,这正是我想知道的。不幸的是,这使得:Dim lastRowIndex作为unionRange中每个currentRow的整数。Rows lastRowIndex=currentRow。row Next currentRow似乎是更干净的解决方案。非常酷的解决方案。我有一个类似的项目,并通过保留行索引区域构建了一个变通方法,但这非常困难effective@CassieD使用areas集合应该运行得更快一些,而且也应该同样简单。因为没有比行更多的区域,而且通常比区域更多的行,所以区域循环必须运行更少的次数。@这是速度上的一个很好的点。我的代码正在处理大量数据,可能需要进一步提高速度。我今天就换。