vba循环遍及非连续范围

时间:2010-04-02 17:34:17

标签: excel vba

我在行上有一个非连续的范围(myRange的示例地址:$ 2:$ 2,$ 4:$ 205,$ 214:$ 214),我想访问该范围内的特定行和列。我尝试过以下方法:

'获取范围内第2行,第1列的值

myRange.rows(2).Cells(, 1).Value

但是,这给了我工作表中第二行的值,而不是在范围内 - 这意味着它给了我$ 3 $ 1的地址 - 而不是$ 4 $ 1

有人可以解释我如何访问我的范围内的值吗? (这可能与不同的领域有关)

谢谢

4 个答案:

答案 0 :(得分:4)

这是我的参赛作品 - 不一定比Irwin的

更好
Function GetValue(rInput As Range, Row As Long, Column As Long) As Variant

    Dim rArea As Range
    Dim lCumRows As Long
    Dim lActualRow As Long

    For Each rArea In rInput.Areas
        lCumRows = lCumRows + rArea.Rows.Count
        If Row <= lCumRows Then
            lActualRow = rArea.Rows(1).Row + (Row - (lCumRows - rArea.Rows.Count + 1))
            Exit For
        End If
    Next rArea

    If lActualRow > 0 Then
        GetValue = rInput.Parent.Cells(lActualRow, Column).Value
    End If

End Function

Function GetValue2(rInput As Range, Row As Long, Column As Long) As Variant

    Dim rRow As Range
    Dim lRowCnt As Long

    For Each rRow In rInput.Rows
        lRowCnt = lRowCnt + 1
        If lRowCnt = lrow Then
            GetValue2 = rRow.Cells(1, Column).Value
            Exit For
        End If
    Next rRow

End Function

然后阅读http://www.dailydoseofexcel.com/archives/2004/07/07/the-strange-object/,了解Excel为何如此表现。

如果你感兴趣的话,测试过程

Sub test()

    Dim myRange As Range

    Set myRange = Union(Rows(2), Range("4:205"), Rows(214))

    Debug.Print GetValue(myRange, 1, 2), GetValue(myRange, 1, 2)
    Debug.Print GetValue(myRange, 2, 2), GetValue(myRange, 2, 2)
    Debug.Print GetValue(myRange, 3, 2), GetValue(myRange, 3, 2)
    Debug.Print GetValue(myRange, 200, 2), GetValue(myRange, 200, 2)

End Sub

答案 1 :(得分:2)

我认为你希望VBA做的是将你的非连续范围视为一个连续范围。我不认为你采取的方法会奏效。您将不得不将此视为多重连续范围。以下代码可以帮助您入门。其中rowSelection是您感兴趣的范围中的行。如果输入2,它将选择工作簿中的第4行,因为它是您范围中的第二行。

Sub Macro1()

    Dim rowCounter As Long
    Dim rowSelection As Long

    rowSelection = 2
    For Each Rng In Range("A2:A2,A4:A205,A214:A214").Areas
         If Rng.Rows.Count >= rowSelection Then
            Rng.Rows(rowSelection - rowCounter).Cells(1, 1).Select
            End
         Else
            rowCounter = rowCounter + Rng.Rows.Count
         End If
    Next Rng

End Sub

答案 2 :(得分:1)

此代码遍历命名范围:

Dim c As Range

x=0

For Each c In Range("MyNamedRange")

    'if x = pick a number and do something here

    MsgBox c.Address & vbTab & c.Value

x=x+1

Next c

答案 3 :(得分:0)

谢谢大家的回答 - 在看到这些答案之前,我自己想出来并且到目前为止它正在发挥作用。我不会说这是最有效的方法,但似乎有效:

 Public Function NextRow(index As Integer, rows As Range) As Range
    Dim i As Integer, r As Range
    i = 1
    Set NextRow = Nothing
    For Each r In rows.rows
        If i = index Then
            Set NextRow = Range(r.Address)
            Debug.Print "NextRow: " & NextRow.Address
            Exit Function
        End If

        i = i + 1
    Next r

End Function

看起来类似的第二个答案 - 从根本上我正在推进到我希望使用的索引范围,而不是返回由地址设置的范围(!important)

我称之为:

NextRow(2, myRange).Cells(,1).value