我们可以在VBScript中重置For循环计数器吗?

时间:2013-01-02 13:21:25

标签: excel-vba vbscript vba excel

我有一个数组说:VMHArray =(12,22,34,4)现在有另一个Arraylist对象说ArrayListTaskDetails保存数据为(12,55,44, 4,12,22,21,107,43,22,34)现在我编写的以下代码用于删除ArrayListTaskDetails中不存在的列表VMHArray中的项目。

代码

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

现在假设在IndexSearch = 0找到匹配项,因此根据它会删除位置0,1,2,3处的元素 - 相当不错。但由于删除并使ArrayList对象与功能连续,其他元素将被4向左移动。现在问题是For Loop已经增加了4,所以它将从location 4的下一次迭代开始。因此,现在数组列表中0 location处的新元素永远不会有机会测试与VMHArray数组元素的相等性。我们是否可以在不失去预期操作的情况下处理这种情况,或者如果我们可以将For Loop计数器设置为其最近的匹配位置,即刚刚找到的匹配项和4个元素已被删除。

如果有任何问题需要了解,请告诉我们!

编辑 Go to无效

CODE(根据@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

谢谢,

3 个答案:

答案 0 :(得分:5)

解决问题的两个想法:

  1. 使用字典检查要保留的项目
  2. 向后循环
  3. 在代码中:

    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(), ".")
    

    输出:

    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
    

    关于.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)
    

答案 1 :(得分:0)

您可以尝试这样的事情

Dim Flag : Flag = true
Dim Counter
Restart:
For IndexSearch = 0 To ArrayListTaskDetails.Count - 1 step 4
Counter = 0
Do while Flag

    If VMHArray(VMHArray) = ArrayListTaskDetails (IndexSearch) Then

      ArrayListTaskDetails.RemoveRange IndexSearch, 4
      Goto Restart
      Flag = False

    End If
Counter = Counter + 1
Loop
Next

答案 2 :(得分:0)

重置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