• Deleting With a For Each Loop

    Author
    Topic
    #475444

    When deleting items in a DOM collection, it is always better to use a For Each loop:

    Code:
    For Each Rng In ActiveDocument.StoryRanges
      For Each Fld In Rng.Fields
       Fld.Delete   
      Next Fld 
    Next Rng  

    Or a backwards countdown:

    Code:
    For currentField = myStory.Fields.Count To 1 Step -1
         myStory.Fields(currentField).Delete 
    Next currentField

    It seems sometimes the For Each approach misses, skips, or gets confused by items in the list.

    Viewing 4 reply threads
    Author
    Replies
    • #1271762

      Hi ForEachLoop,

      Using a For Each Loop is more efficient than iterating through a collection via a counter (whether forwards or backwards). When using a counter for item deletion, you need to go backwards; otherwise every second instance will be missed. There’s nothing about the For Each Loops in your first code snippet that would explain any errant behaviour – works fine for me.

      Cheers,
      Paul Edstein
      [Fmr MS MVP - Word]

    • #1271783

      How about this (with only one uncommented Delete statement each time, and manually deleting all the lines before each run)? Only the last case deletes all the lines.

      Code:
       
      Public Sub TestLines()
      On Error GoTo MyErrorHandler
       
      ‘Sets up a lot of lines
      Dim i As Long
      For i = 1 To 300
           ActiveDocument.Shapes.AddLine 10, i * 2, 2000, i * 2
      DoEvents
      Next
       
      Dim myShape As Shape
      For Each myShape In ActiveDocument.Shapes
           ‘myShape.Delete
       
      DoEvents
      Next
       
      Dim j As Long
      For j = 1 To 300
           ‘ActiveDocument.Shapes(j).Delete
      DoEvents
      Next
       
      Dim k As Long
      For k = ActiveDocument.Shapes.Count To 1 Step -1
           ‘ActiveDocument.Shapes(k).Delete
      DoEvents
      Next
       
      MsgBox “Shapes remaining: ” & ActiveDocument.Shapes.Count
       
      Exit Sub
      MyErrorHandler:
      MsgBox “TestLines” & vbCrLf & vbCrLf & “Err = ” & Err.Number & vbCrLf & “Description: ” & Err.Description
      End Sub
      
    • #1271915

      Hi ForEachLoop,

      As you’ve apparently discovered, a For Each loop behaves differently when deleting items from the shapes collection than it does when deleting items from the fields collection. I’d call it a bug.

      Cheers,
      Paul Edstein
      [Fmr MS MVP - Word]

    • #1272119

      Just out of interest, what version of Word did you use to test this? I use 2003 SP3, and for me the For Each routine works correctly.

      I’ve seen comments elsewhere (http://social.msdn.microsoft.com/Forums/en/isvvba/thread/a974f1e4-ed02-4b68-8ee5-6d7389cc719d, for example) that suggest that Word 2010 works differently – and, presumably, incorrectly.

    • #1272123

      My favourite solution to this type of problem is

      Code:
      With ActiveDocument
        While .Shapes.Count > 0
          .Shapes(1).Delete
        Wend
      End With
    Viewing 4 reply threads
    Reply To: Deleting With a For Each Loop

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: