Удалить элемент во время цикла for - PullRequest
0 голосов
/ 14 ноября 2011

Что содержит tlist после того, как я:

Dim tlist As Collection
tlist.Add ("AA")
tlist.Add ("BB")
tlist.Add ("CC")
tlist.Add ("DD")

For i = 1 To tlist.Count
    If i = 2 Then tList.Remove (2)
Next

Я надеюсь, что это будет:

Index | Value
-------------
1     |  "AA"
3     |  "BB"
4     |  "CC"

Но я боюсь, что это будет:

Index | Value
-------------
1     |  "AA"


Вот так выглядит мой код:

Dim tlist As Collection
tlist.Add ("KA")
tlist.Add ("KIC")
tlist.Add ("KS")
tlist.Add ("NC")

' Loop through each cell in row.
For Each mycells In myrow.Columns
    Dim i As Integer

    ' Loop through each regex in list.
    For i = 1 To tlist.Count
        matches = Regex(tlist(i))

        ' If match found in cell, copy row, and remove element (to prevent duplicate rows).
        If matches >= 1 Then
            Call CopyRow(myrow, _
                         ActiveSheet.Index, _
                         ActiveSheet.Index + i)

            tlist.Remove (i)
        End If
    Next
Next

Является ли Collection даже правильным типом данных для использования?

Ответы [ 3 ]

3 голосов
/ 14 ноября 2011

Чтобы ответить на ваш первый вопрос, предметом, удаленным из коллекции, будет «BB». Остальные предметы останутся. Вы просто удаляете второй элемент в списке: .Remove (2)

Чтобы ответить на ваш второй вопрос: это зависит от того, что вы делаете. Я почти всегда предпочитаю работать с объектом словаря. Он обладает большей функциональностью, и вы можете проверить, существует ли элемент, и назначить элемент для каждой клавиши.

'// Using With but you could use Set dic = CreateObject("Scripting.Dictionary")
With CreateObject("Scripting.Dictionary")

    .Add "AA", Nothing
    .Add "BB", Nothing
    .Add "CC", Nothing
    .Add "DD", Nothing

    If .exists("BB") Then .Remove ("BB")

    For Each Key In .keys
      Debug.Print Key
    Next Key

End With

Над отпечатками кодов AA, CC, DD

1 голос
/ 14 ноября 2011

Я согласен с Reafidy, Dictionary будет работать лучше.

В вашем коде также есть ряд других проблем.Вот переработанная версия.Обратите внимание, что я использовал раннее связывание, поэтому установите ссылку на Microsoft Scripting Runtime и Microsoft VBScript Regular expressions 5.5

Sub Muntoo()
    Dim re As RegExp
    Dim myCells As Range
    Dim myRow As Range
    Dim Key As Variant
    Dim tlist As Dictionary

    On Error GoTo EH

    Set tlist = New Dictionary
    Set re = New RegExp

    tlist.Add 1, "KA"
    tlist.Add 2, "KIC"
    tlist.Add 3, "KS"
    tlist.Add 4, "NC"

    ' Set row reference 
    Set myRow = Intersect(ActiveSheet.UsedRange, ActiveCell.EntireRow)  

    re.Global = True ' or false
    re.IgnoreCase = True ' or false

    ' Loop through each cell in row.
    For Each myCells In myRow.Cells
        ' Loop through each regex in list.
        If myCells.Value <> "" Then
            For Each Key In tlist.Keys
                re.Pattern = tlist.Item(Key)
                ' If match found in cell, copy row, and remove element (to prevent duplicate rows).
                If re.Test(myCells.Value) Then
                    Call CopyRow(myRow, _
                                 ActiveSheet.Index, _
                                 ActiveSheet.Index + Key)

                    tlist.Remove Key
                End If
            Next
        End If
    Next
CleanUp:
    On Error Resume Next
    Set re = Nothing
    tlist.RemoveAll
    Set tlist = Nothing
Exit Sub
EH:
    Resume
    GoTo CleanUp
End Sub

Private Sub CopyRow(rng As Range, i1 As Long, i2 As Long)

End Sub
0 голосов
/ 14 ноября 2011

Не совсем точно, но если вы хотите удалить элемент по указанному индексу, вам следует посмотреть на принятый ответ на этот вопрос:

Удаление элементов в массиве, если элемент является определеннымзначение VBA

Кажется, делать то, что вы хотите:)

...