2014-10-29 92 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