vba 我们可以在 VBScript 中重置 For 循环计数器吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14122838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we reset For loop counter in VBScript?
提问by CodeLover
I have an Array say: VMHArray
= (12,22,34,4) Now have another Arraylist
object say ArrayListTaskDetails
holding the data as (12,55,44,4,12,22,21,107,43,22,34) Now the below code I wrote to remove items from the list ArrayListTaskDetails
which are not present in the VMHArray
.
我有一个数组说:VMHArray
= (12,22,34,4) 现在有另一个Arraylist
对象说ArrayListTaskDetails
将数据保存为 (12,55,44,4,12,22,21,107,43,22,34) 现在下面的代码我写信从列表中删除ArrayListTaskDetails
不存在于VMHArray
.
Code
代码
Dim Flag : Flag = true
Dim Counter
For IndexSearch = 0 To ArrayListTaskDetails.Count - 1 step 4
Counter = 0
Do while Flag
If VMHArray(Counter) <> ArrayListTaskDetails (IndexSearch) Then
ArrayListTaskDetails.RemoveRange IndexSearch, 4
Flag = False
End If
Counter = Counter + 1
Loop
Next
Now Suppose a match found at IndexSearch = 0
,so according it would delete the element at locations 0,1,2,3
- quite good. But due to removal and to make the ArrayList
object contiguous by functionality other elements will be shifted by 4
to left. Now the problem is as For Loop
already incremented by 4,so it would start from next iteration from location 4
. Thus now the new element at 0 location
in the array list can never get a chance to test the equality with the VMHArray
array elements. Can we handle such scenario without loosing the intended operation or anyway if we can set the For Loop
counter to its immediate position,where the just recent match found and 4 elements removed.?
现在假设在 处找到匹配项IndexSearch = 0
,因此根据它会删除位置处的元素0,1,2,3
- 非常好。但是由于移除并ArrayList
通过功能使对象连续,其他元素将4
向左移动。现在问题For Loop
已经增加了 4,所以它将从location 4
. 因此,现在0 location
数组列表中的新元素永远不会有机会测试与VMHArray
数组元素的相等性。我们是否可以在不丢失预期操作的情况下处理这种情况,或者我们是否可以将For Loop
计数器设置为其直接位置,即找到最近的匹配项并删除 4 个元素。
If any issue to understand the problem,let me know please!
如果有任何问题要理解问题,请告诉我!
EDITGo to
will not work
编辑Go to
将不起作用
CODE(as per @Ankit suggestion)
代码(根据@Ankit 建议)
Option Explicit
Dim Flag : Flag = true
Dim Counter
Dim VMHArray : VMHArray = Array(12,22,34,4)
Dim ArrayListTaskDetails : Set ArrayListTaskDetails = CreateObject("System.Collections.ArrayList")
ArrayListTaskDetails.Add(45)
ArrayListTaskDetails.Add(4)
ArrayListTaskDetails.Add(22)
ArrayListTaskDetails.Add(4)
ArrayListTaskDetails.Add(45)
ArrayListTaskDetails.Add(20)
ArrayListTaskDetails.Add(12)
ArrayListTaskDetails.Add(35)
ArrayListTaskDetails.Add(34)
Restart:
For IndexSearch = 0 To ArrayListTaskDetails.Count - 1 step 4
Counter = 0
Do while Flag
If VMHArray(Counter) <> ArrayListTaskDetails (IndexSearch) Then
ArrayListTaskDetails.RemoveRange IndexSearch, 4
Goto Restart
Flag = False
End If
Counter = Counter + 1
Loop
Next
MsgBox(Join(ArrayListTaskDetails.ToArray()),"$")
Thanks,
谢谢,
回答by Ekkehard.Horner
Two ideas to solve the problem:
解决问题的两个思路:
- use a dictionary to check for the items to keep
- loop backwards
- 使用字典检查要保留的项目
- 向后循环
In code:
在代码中:
Option Explicit
Dim alSrc : Set alSrc = CreateObject("System.Collections.ArrayList")
Dim sE
For Each sE In Split("a x x x b x x x c x x x d x x x e x x x f x x x a x x x")
alSrc.Add sE
Next
WScript.Echo "alSrc:", Join(alSrc.ToArray(), ".")
Dim aKeep : aKeep = Split("a d")
WScript.Echo "aKeep:", Join(aKeep, ".")
Dim dicKeep : Set dicKeep = CreateObject("Scripting.Dictionary")
For Each sE In aKeep
dicKeep(sE) = 0
Next
WScript.Echo "dicKeep:", Join(dicKeep.Keys(), ".")
Dim nI
For nI = alSrc.Count - 4 To 0 Step -4
sE = alSrc(nI)
If Not dicKeep.Exists(sE) Then
alSrc.RemoveRange nI, 4
End If
WScript.Echo sE, nI, Join(alSrc.ToArray(), ".")
Next
WScript.Echo "alSrc:", Join(alSrc.ToArray(), ".")
output:
输出:
alSrc: a.x.x.x.b.x.x.x.c.x.x.x.d.x.x.x.e.x.x.x.f.x.x.x.a.x.x.x
aKeep: a.d
dicKeep: a.d
a 24 a.x.x.x.b.x.x.x.c.x.x.x.d.x.x.x.e.x.x.x.f.x.x.x.a.x.x.x
f 20 a.x.x.x.b.x.x.x.c.x.x.x.d.x.x.x.e.x.x.x.a.x.x.x
e 16 a.x.x.x.b.x.x.x.c.x.x.x.d.x.x.x.a.x.x.x
d 12 a.x.x.x.b.x.x.x.c.x.x.x.d.x.x.x.a.x.x.x
c 8 a.x.x.x.b.x.x.x.d.x.x.x.a.x.x.x
b 4 a.x.x.x.d.x.x.x.a.x.x.x
a 0 a.x.x.x.d.x.x.x.a.x.x.x
alSrc: a.x.x.x.d.x.x.x.a.x.x.x
As to the mystery of .Count - ?:
至于 .Count - ? 的奥秘:
1 2 3 4 5 6 7 8 - Count 1 - 8
0 1 2 3 4 5 6 7 - Idx 0 - 7
A x x x B x x x - Count (8) - Step (4) = Pos to check (4)
Count (8) - Step + 1 (5) = Not the pos to check (3)
回答by bonCodigo
Resetting For loop counter
means you somewhat do not let it iterate
. You have to be very careful not to run into an infinite loop
. Frankly not reading your huge text. But looking at your code and title, please do try the following:
重置For loop counter
意味着你有点不让它iterate
。您必须非常小心,以免遇到infinite loop
. 坦率地说,没有阅读你的大文本。但是查看您的代码和标题,请尝试以下操作:
For IndexSearch = 0 To ArrayListTaskDetails.Count - 1 step 4
Counter = 0
Do while Flag
If VMHArray(Counter) = ArrayListTaskDetails (IndexSearch) Then
ArrayListTaskDetails.RemoveRange IndexSearch, 4
Flag = False
If IndexSearch >= 4 then
IndexSearch = IndexSearch - 4 '-- add this to go back to previous index
End If
End If
Counter = Counter + 1
Loop
Next IndexSearch