每个循环的反向顺序

sir*_*lus 35 excel foreach vba excel-vba

VB最强大的功能之一是能够循环访问集合中的对象而不引用索引for each循环.

我发现它只是想从集合中删除对象非常有用.

当从预定义的表格(如电子表格中的行)中删除对象时,如果我使用索引并从最大值开始并返回第一个,则代码更简单.(带迭代器的步骤-1)(否则需要一个偏移量,因为For每次将枚举器指针移回前一个对象,一旦删除活动对象)

例如.

For intA = 10 to 1 step -1 
    ' ...
Next
Run Code Online (Sandbox Code Playgroud)

使用For Each时怎么样?接下来例如.

For each rngCell in Selection.Cells
    ' ...
Next
Run Code Online (Sandbox Code Playgroud)

我怎么能使用循环语法向后for each循环?

Hub*_*san 22

使用for each循环语法不可能向后循环.

作为替代方案,您可以使用For i = a To 1 Step -1循环:

Sub reverseForEach()
    Dim i As Long, rng As Range

    Set rng = ActiveSheet.Range("A1:B2")

    For i = rng.Cells.Count To 1 Step -1

        Debug.Print rng.item(i).Address
        ' Or shorthand rng(i) as the Item property 
        ' is the default property for the Range object.
        ' Prints: $B$2, $A$2, $B$1, $A$1

    Next i

End Sub
Run Code Online (Sandbox Code Playgroud)

这适用于具有Item属性的所有集合.例如工作表,区域或形状.

注意:在Range对象上使用时循环的顺序是从右到左,然后是向上.


chr*_*sen 20

对于内置集合(例如a Range),简短的答案是:你不能.对于用户定义的集合,由@VBlades链接的答案可能很有用,尽管成本可能超过好处.

一种解决方法是分离要从实际移除中移除的物品的识别.例如,对于范围,使用构建新的范围变量Union,然后处理该变量,例如一次删除所有行.对于Range例如,你也可以采取优势Variant Array的方法,进一步加快速度.

这些是否有用将取决于您的实际用例.


ash*_*awg 6

还有其他很好的答案,但这里有另一种通过范围“后退”的替代方法。


将范围转换为数组的函数

此函数返回一个“向后范围数组”,可用于For..Each

Function ReverseRange(rg As Range) As Range()
    Dim arr() As Range, r As Long, c As Long, n As Long
    With rg
        ReDim arr(1 To .Cells.Count) 'resize Range Array
        For r = .Cells(.Rows.Count, 1).Row To .Cells(1, 1).Row Step -1
            For c = .Cells(1, .Columns.Count).Column To .Cells(1, 1).Column Step -1
                n = n + 1
                Set arr(n) = .Worksheet.Cells(r, c) 'set cell in Array
            Next c
        Next r
    End With
    ReverseRange = arr  'return Range Array as function result
End Function
Run Code Online (Sandbox Code Playgroud)

示例用法:

Sub test()
    Dim oCell
    For Each oCell In ReverseRange(ActiveSheet.Range("E5:A1"))

        Debug.Print oCell.Address 'do something here with each cell

    Next oCell
End Sub
Run Code Online (Sandbox Code Playgroud)