Excel VBA Range.Rows迭代器处理的行的顺序

时间:2014-10-29 15:13:47

标签: excel vba excel-vba

我需要遍历从电子表格底部到电子表格顶部的范围。范围可以是不连续的,但我已经删除了重叠(我只关注行顺序,因此我还将列缩小为" A")并将范围放在& #34; Overall_Range&#34 ;.由于区域可以按任何顺序进入范围,因此我构建了一个函数Ge​​t_Loop_Order,该函数返回一个数组,其中应该处理区域从下到上的顺序。我的计划是迭代遍历每个区域(从下到上),如下所示:

Loop_Order = Get_Loop_Order(Overall_Range)
For A = LBound(Loop_Order) To UBound(Loop_Order)
  For Each this_row In Overall_Range.Areas(Loop_Order(A)).Rows
    ... do stuff ...
  Next this_row
Next A

我意识到Range.Rows上的For Each不会以相反的顺序处理(事实上,据我所知,我根本不保证订单)。

有没有人知道是否有办法循环确保以特定行顺序发生的范围?当我选择时(使用单词"选择"这里不应该与Excel VBA术语混淆"选择,"上面的代码使用" Overall_Range")从底部到顶部的范围(A10:A2)循环按此顺序排列,当我从上到下选择一个范围(A2:A10)时,它按此顺序排列。我不知道如果我做像Union这样的事情会发生什么(A10:A2,A1:A2)。我认为我必须编写另一个函数来返回一个带有处理事物顺序的数组,但是如果别人有另一个解决方案,我会喜欢它。你能帮忙吗?

更新:

我做了更多测试以下是代码:

Dim my_range As Range 'Range being tested
Dim N As Long         'Loop variable when numbers are needed
Dim M As Range        'Loop variable when ranges are needed

Set my_range = ActiveSheet.Range("A2:A10")

ActiveSheet.Range("B1").Value = "A2:A10"
ActiveSheet.Range("B1").Font.Bold = True
ActiveSheet.Range("B1").HorizontalAlignment = xlCenter
ActiveSheet.Range("B1:C1").Merge
ActiveSheet.Range("B2").Value = "Row Index"
ActiveSheet.Range("B2").Font.Bold = True
ActiveSheet.Range("B2").HorizontalAlignment = xlCenter
ActiveSheet.Range("C2").Value = "Row Iterator"
ActiveSheet.Range("C2").Font.Bold = True
ActiveSheet.Range("C2").HorizontalAlignment = xlCenter

For N = 1 To my_range.Rows.Count
    ActiveSheet.Range("B" & N + 2).Value = my_range.Rows(N).Row
Next N

N = 1
For Each M In my_range.Rows
    ActiveSheet.Range("C" & N + 2).Value = M.Row
    N = N + 1
Next M

Set my_range = ActiveSheet.Range("A10:A2")

ActiveSheet.Range("D1").Value = "A10:A2"
ActiveSheet.Range("D1").Font.Bold = True
ActiveSheet.Range("D1").HorizontalAlignment = xlCenter
ActiveSheet.Range("D1:E1").Merge
ActiveSheet.Range("D2").Value = "Row Index"
ActiveSheet.Range("D2").Font.Bold = True
ActiveSheet.Range("D2").HorizontalAlignment = xlCenter
ActiveSheet.Range("E2").Value = "Row Iterator"
ActiveSheet.Range("E2").Font.Bold = True
ActiveSheet.Range("E2").HorizontalAlignment = xlCenter

For N = 1 To my_range.Rows.Count
    ActiveSheet.Range("D" & N + 2).Value = my_range.Rows(N).Row
Next N

N = 1
For Each M In my_range.Rows
    ActiveSheet.Range("E" & N + 2).Value = M.Row
    N = N + 1
Next M

Set my_range = Union(ActiveSheet.Range("A10:A2"), ActiveSheet.Range("A1:A2"))

ActiveSheet.Range("F1").Value = "UNION(A10:A2,A1:A2)"
ActiveSheet.Range("F1").Font.Bold = True
ActiveSheet.Range("F1").HorizontalAlignment = xlCenter
ActiveSheet.Range("F1:G1").Merge
ActiveSheet.Range("F2").Value = "Row Index"
ActiveSheet.Range("F2").Font.Bold = True
ActiveSheet.Range("F2").HorizontalAlignment = xlCenter
ActiveSheet.Range("G2").Value = "Row Iterator"
ActiveSheet.Range("G2").Font.Bold = True
ActiveSheet.Range("G2").HorizontalAlignment = xlCenter

For N = 1 To my_range.Rows.Count
    ActiveSheet.Range("F" & N + 2).Value = my_range.Rows(N).Row
Next N

N = 1
For Each M In my_range.Rows
    ActiveSheet.Range("G" & N + 2).Value = M.Row
    N = N + 1
Next M

Set my_range = Union(ActiveSheet.Range("A10:A2"), ActiveSheet.Range("A1:A2"), ActiveSheet.Range("A11:A12"))

ActiveSheet.Range("H1").Value = "UNION(A10:A2,A13:A15,A11:A12)"
ActiveSheet.Range("H1").Font.Bold = True
ActiveSheet.Range("H1").HorizontalAlignment = xlCenter
ActiveSheet.Range("H1:I1").Merge
ActiveSheet.Range("H2").Value = "Row Index"
ActiveSheet.Range("H2").Font.Bold = True
ActiveSheet.Range("H2").HorizontalAlignment = xlCenter
ActiveSheet.Range("I2").Value = "Row Iterator"
ActiveSheet.Range("I2").Font.Bold = True
ActiveSheet.Range("I2").HorizontalAlignment = xlCenter

For N = 1 To my_range.Rows.Count
    ActiveSheet.Range("H" & N + 2).Value = my_range.Rows(N).Row
Next N

N = 1
For Each M In my_range.Rows
    ActiveSheet.Range("I" & N + 2).Value = M.Row
    N = N + 1
Next M

结果是我无法发布的内容,因为我无法发布图片......叹息......他们表明无论范围多么疯狂,当通过Rows集合访问时,它们按行顺序排列。

这似乎表明,如果我通过Rows集合访问它,无论我对该范围做什么疯狂的事情都会按顺序返回行。我认为这意味着只是在范围内倒退(如评论中所示)的方法将有效。

1 个答案:

答案 0 :(得分:3)

这段代码可以解决问题。

有一个澄清:从VBA角度来看,Range("A2:A10")Range("A10:A2")完全相同(即他们返回相同的地址:$A$2:$A$10)。为了循环,你需要传递另一个参数。

修改

这需要您提供的Overall_Range,然后UpDown的方向会将值分配给要在For语句中使用的变量。

未使用任何选项。

Option Explicit

Sub LoopOrderTest()
    Dim Overall_Range As Range
    Dim sLoopDir As String
    Dim iTtlRows As Integer
    Dim iLoopStep As Integer
    Dim iLoopFrom As Integer
    Dim iLoopTo As Integer
    Dim n As Integer

    Set Overall_Range = Range("A2:A10")
    sLoopDir = "Up" 'or "Down"

    iTtlRows = Overall_Range.Rows.Count 'Get total rows

    'Assign for loop control items based on sLoopDir value
    If sLoopDir = "Up" Then
        iLoopFrom = 1
        iLoopTo = iTtlRows
        iLoopStep = 1
    ElseIf sLoopDir = "Down" Then
        iLoopFrom = iTtlRows
        iLoopTo = 1
        iLoopStep = -1
    End If

    Dim i As Integer 'used only to put items in cells for testing
    i = 1

    For n = iLoopFrom To iLoopTo Step iLoopStep
        'do stuff.
        'for now just print a number showing the order that the loop works through
        Overall_Range.Cells(n, 1).Value = i
        i = i + 1
    Next n
End Sub

这显示了当我设置sLoopDir = "Up"并运行代码时会发生什么。数字上升表示它从上到下循环。

top to bottom

这显示了当我设置sLoopDir = "Down"并运行代码时会发生什么。数字下降表示它从下到上循环。

bottom to top