Some recent threads have had to do with deleting objects from Word documents. As the posts show, when deleting objects, you’re usually confined to using a For…Next loop rather than the much faster For…Each loop.
But in some cases, there’s a third alternative that I haven’t seen discussed before (though I admittedly didn’t look very hard) that offers nearly the same speed as a For…Each loop, but with the flexibility to delete objects along the way found in a For…Next loop.
One such case is with Paragraphs, obviously something that you might often need to iterate and occasionally delete.
Paragraphs, along with a handful of other objects (fields ar e another), include a “Next” property, which returns the next object in the series. By using the Next property, you can quickly move along a collection, while still being able to delete items along the way if needed.
The following three examples don’t actually delete paragraphs — I thought I’d keep it simple for illustration purposes — but they do nicely illustrate the three different techniques for iterating Paragraphs in a Word doucment. I ran all three on the same, 252-page, 4,030-paragraph Word document.
- The first uses a For…Next loop, and was quite slow, as you might expect. 2 minutes, 20 seconds.
- The second uses a For…Each loop, and was a bit speedier, at 2 seconds (yup!)
- The third, which starts at the first paragraph and uses the Next property to move along, also took … 2 seconds
Sub IterateParasTheSlowWay() Dim doc As Document Dim para As Paragraph Dim k As Integer Set doc = ActiveDocument For k = doc.Paragraphs.count To 1 Step -1 Set para = doc.Paragraphs(k) If para.Style = doc.Styles(wdStyleHeading1) Then para.Range.HighlightColorIndex = wdBrightGreen End If Next k End Sub '---------------------------------------------------------- Sub IterateParasTheFastestWay() Dim doc As Document Dim para As Paragraph Set doc = ActiveDocument For Each para In doc.Paragraphs If para.Style = doc.Styles(wdStyleHeading1) Then para.Range.HighlightColorIndex = wdBrightGreen End If Next para End Sub '------------------------------------------------------------ Sub IterateParasTheFastAndFlexibleWay() Dim doc As Document Dim para As Paragraph Dim paraNext As Paragraph Set doc = ActiveDocument Set para = doc.Paragraphs.First Do While Not para Is Nothing Set paraNext = para.Next If para.Style = doc.Styles(wdStyleHeading1) Then para.Range.HighlightColorIndex = wdBrightGreen End If Set para = paraNext Loop End Sub
In the case of this last subroutine, instead of applying highlighting, I could just as easily have deleted those Heading 1 paragraphs, and still been able to move along the collection correctly, since I’ve already got my hands on the following paragraph, which becomes the current paragraph on the next trip through the loop.
For…Each loops are still my weapon of choice when doing standard iterations, but using the Next property technique (the “linked-list method” formally) has proved a valuable additon to my Word macro toolbox.
Cheers!