2014-10-29 90 views
2

我需要遍历从电子表格底部到电子表格顶部的一个范围。范围可以是不连续的,但我删除了重叠(我只关心行顺序,所以我也将列缩小到“A”),并将范围放在“Overall_Range”中。由于区域可以以任何顺序进入范围,因此我创建了一个函数Ge​​t_Loop_Order,该函数返回一个数组,其顺序应该是从底部到顶部处理区域。我的计划是只遍历每个区域(从底部到顶部)是这样的:Excel VBA Range.Rows处理行的迭代器顺序

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不会以相反的顺序进行处理(其实,我也不能保证根据我所知道的顺序)。

有谁知道是否有方法来循环遍历保证以特定行顺序发生的范围?当我选择时(在这里使用单词“select”不应该与Excel VBA术语“选择”混淆,上面的代码使用“Overall_Range”)从下到上的范围(A10:A2)顺序,当我从上到下选择一个范围(A2:A10)时,按顺序排列。我不知道如果我做联合(A10:A2,A1:A2)会发生什么情况。我在想,我将不得不编写另一个返回数组的函数来处理事情,但如果别人有另一个解决方案,我会喜欢它。你能帮我吗?

UPDATE:

我做了一些更多的测试,下面是代码:

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集合访问范围,我都会对范围做些什么疯狂的事情,从而始终如一地返回行。我在想,这意味着只是在整个范围后退(如评论中所建议的那样)的方法将起作用。

+3

为什么你必须使用'对于Each'而不是“对于n = Range.Rows.Count 1步-1'例如? – Rory 2014-10-29 15:20:46

+0

也许你可以检查不是只对选定行(当选择A2:A10时为'2',或者在任何选择中的第一行 - 无论是从顶部还是从底部开始选择),还有活动单元行(这将是所选第一行的行)不是一个真正的答案,但也许是一些定向帮助 – guitarthrower 2014-10-29 15:51:36

+0

@Rory:这是一个很好的建议,可以在确定选择是从顶部还是从底部开始后使用 – guitarthrower 2014-10-29 15:52:34

回答

2

此代码应该做的伎俩。

利用一种澄清:从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

+0

我认为你的解决方案根本就不考虑ActiveCell。我一直需要按相反顺序处理范围。然而,对“A2:A10”的回答与“A10:A2”(例如$ A $ 2:$ A $ 10)完全相同的范围是我真正需要的,因此您的答案得到了支票。 – bfish 2014-10-30 11:11:36

+0

优秀。你的问题是要求两个方向,因此我的回应。很高兴为你工作。 – guitarthrower 2014-10-30 15:44:45