One of the most powerful things about VB is ability to loop through objects in a collection WITHOUT referring to the index - for each
loop.
VB最强大的功能之一是能够在一个集合中对对象进行循环,而不需要对每个循环引用索引。
I find it very useful only want to remove objects from a collection.
我发现从集合中删除对象非常有用。
When doing removing objects from a predefined such as rows on a spread sheet the code is simpler if I use indexing and start at the largest and work back to the first. (Step -1 with an iterator) (otherwise requires an offset as the For each moves the enumerator pointer back to the previous object once the active one is deleted)
当从一个预定义的对象(如扩展表上的行)中删除对象时,如果我使用索引并从最大的开始,并从第一个开始工作,代码会更简单。(带有迭代器的步骤-1)(否则需要一个偏移量,因为每次删除活动的对象时,枚举器指针都会返回到先前的对象)
eg.
如。
For intA = 10 to 1 step -1
' ...
Next
What about when using a For Each | Next eg.
那么,对于每个|使用a的情况如何呢?
For each rngCell in Selection.Cells
' ...
Next
How could I loop backwards using the for each
loop syntax?
如何使用for每个循环语法向后循环?
3 个解决方案
#1
14
An alternative using "For x = a To b Step -1" for a collection of cells:
对单元格集合使用“For x = a To b Step -1”的替代方法:
Sub reverseForEach()
Dim lngCounter As Long, rng As Range
Set rng = ActiveSheet.Range("A1:B5")
For lngCounter = rng.Cells.Count To 1 Step -1
Debug.Print rng(lngCounter).Address
'rng(lngCounter) is shorthand for rng.item(lngCounter)
Next lngCounter
End Sub
This should work with most collections that have the .item property.
这应该适用于大多数具有.item属性的集合。
#2
17
For built in collections (eg a Range
) the short answer is: you can't. For user defined collections the answer linked by @VBlades might be useful, although the cost might outweigh the benifit.
对于内置的集合(如范围),简单的答案是:你不能。对于用户定义的集合,@ vblade链接的答案可能是有用的,尽管成本可能超过收益。
One work around is to seperate the identification of items to be removed from the actual removal. Eg, for a range, build up a new range variable using Union
, then process that variable, eg delete all the rows in one go. For the Range
example, you can also take advantage of the Variant Array
method to further speed things up.
其中一项工作是将要删除的项目的标识从实际删除中分离出来。对于一个范围,使用Union构建一个新的范围变量,然后处理该变量,例如一次删除所有的行。对于范围示例,您还可以利用变量数组方法进一步加快速度。
Whether or not any of this is useful will depend on your actual use case.
这些是否有用将取决于您的实际用例。
#3
0
use a second variable that is set as your wanted counter and use this one in your code
使用第二个设置为所需计数器的变量,并在代码中使用这个变量
'ex: Loop from n = 19 to 16
For i = 0 To 3
n = 19 - i
'your code here using n as the counter
Next
#1
14
An alternative using "For x = a To b Step -1" for a collection of cells:
对单元格集合使用“For x = a To b Step -1”的替代方法:
Sub reverseForEach()
Dim lngCounter As Long, rng As Range
Set rng = ActiveSheet.Range("A1:B5")
For lngCounter = rng.Cells.Count To 1 Step -1
Debug.Print rng(lngCounter).Address
'rng(lngCounter) is shorthand for rng.item(lngCounter)
Next lngCounter
End Sub
This should work with most collections that have the .item property.
这应该适用于大多数具有.item属性的集合。
#2
17
For built in collections (eg a Range
) the short answer is: you can't. For user defined collections the answer linked by @VBlades might be useful, although the cost might outweigh the benifit.
对于内置的集合(如范围),简单的答案是:你不能。对于用户定义的集合,@ vblade链接的答案可能是有用的,尽管成本可能超过收益。
One work around is to seperate the identification of items to be removed from the actual removal. Eg, for a range, build up a new range variable using Union
, then process that variable, eg delete all the rows in one go. For the Range
example, you can also take advantage of the Variant Array
method to further speed things up.
其中一项工作是将要删除的项目的标识从实际删除中分离出来。对于一个范围,使用Union构建一个新的范围变量,然后处理该变量,例如一次删除所有的行。对于范围示例,您还可以利用变量数组方法进一步加快速度。
Whether or not any of this is useful will depend on your actual use case.
这些是否有用将取决于您的实际用例。
#3
0
use a second variable that is set as your wanted counter and use this one in your code
使用第二个设置为所需计数器的变量,并在代码中使用这个变量
'ex: Loop from n = 19 to 16
For i = 0 To 3
n = 19 - i
'your code here using n as the counter
Next