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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 19:02:31  来源:igfitidea点击:

Can we reset For loop counter in VBScript?

excel-vbavbscriptvbaexcel

提问by CodeLover

I have an Array say: VMHArray= (12,22,34,4) Now have another Arraylistobject say ArrayListTaskDetailsholding 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 ArrayListTaskDetailswhich 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 ArrayListobject contiguous by functionality other elements will be shifted by 4to left. Now the problem is as For Loopalready incremented by 4,so it would start from next iteration from location 4. Thus now the new element at 0 locationin the array list can never get a chance to test the equality with the VMHArrayarray elements. Can we handle such scenario without loosing the intended operation or anyway if we can set the For Loopcounter 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 towill 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()),"$")

Error

错误

Thanks,

谢谢,

回答by Ekkehard.Horner

Two ideas to solve the problem:

解决问题的两个思路:

  1. use a dictionary to check for the items to keep
  2. loop backwards
  1. 使用字典检查要保留的项目
  2. 向后循环

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 countermeans 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