speed iterating through paragraphs

K

k-risc

I have different Word documents, that I want to convert to xml based
on the styles. Other operations have to be done as well, it's not only
about iteratin through the paragraphs (tables have to be taken care
of, for example).

But there is this loop:
p = 1
While p <= ActiveDocument.Paragraphs.Count
With ActiveDocument.Paragraphs(p).Range
ActiveDocument.Range(.Start, .End - 1).Select
End With
Select Case ActiveDocument.Paragraphs(p).Style
Case "Format 1"
do this
Case "Format 2"
do that
End Select
p = p + 1
Wend

The loop analyzes the content of the paragraph, it's format, and
inserts text at the beginning and/or the end, replaces the content,
changes the style of the paragraph.

It ran pretty fast for a smaller document, but now I have a big
document and the script runs very, very slow.

Therefore I wrote a test routine, that only executes the above while
loop, selects each paragraph, but does not do the select. It simply
selects each paragraph.

The smaller document contains 692 paragraphs, the test routine takes 5
seconds to run.
The bigger document contains 8210 paragraphs and takes 9 minutes and
28 seconds to run.

So it seems that the time per paragraph is like ten times bigger for
this file, making the whole script very slow.

What could be the cause for this?

I know that not only selecting each paragraph but changing it's
contents provokes re-alignment of the text which slows everything
down. That's for sure. But still I can see that with the smaller
document it goes much faster, for the longer document it's not only
slower by the factor of paragraphs it contains more, but there seems
to be something else slowing it dowwn drastically.

Regards,

Chrstian Kirchhoff
 
D

Doug Robbins - Word MVP

I do not understand the purpose of this construction:

With ActiveDocument.Paragraphs(p).Range
ActiveDocument.Range(.Start, .End - 1).Select
End With

But I would use

Dim i as long
With ActiveDocument
For i = 1 to .Paragraphs.Count
Select Case .Paragraphs(i).Style
Case "Format 1"
do this
Case "Format 2"
do that
End Select
Next i
End With


--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP, originally posted via msnews.microsoft.com
 
G

Greg Maxey

Chrstain,

I can't offer an explaination as to why, but you might try something like
this:

Sub ScratchMacro()
Dim StartTime As Single
Dim aPara As Range
StartTime = Timer
With ActiveDocument.StoryRanges(wdMainTextStory)
Set aPara = .Paragraphs(1).Range
Do
Select Case aPara.Style
Case "Format 1"
'do this
Case "Format 2"
'do that
End Select
aPara.Collapse wdCollapseEnd
aPara.MoveEnd wdParagraph, 1
Loop Until aPara.End = .End
End With
Set aPara = Nothing
MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
End Sub

It doesn't physically move the selection so it might be faster.
 
K

k-risc

Chrstain,

I can't offer an explaination as to why, but you might try something like
this:

Sub ScratchMacro()
Dim StartTime As Single
Dim aPara As Range
StartTime = Timer
With ActiveDocument.StoryRanges(wdMainTextStory)
  Set aPara = .Paragraphs(1).Range
  Do
     Select Case aPara.Style
         Case "Format 1"
           'do this
        Case "Format 2"
           'do that
      End Select
      aPara.Collapse wdCollapseEnd
      aPara.MoveEnd wdParagraph, 1
  Loop Until aPara.End = .End
End With
Set aPara = Nothing
MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
End Sub

It doesn't physically move the selection so it might be faster.













--
Greg Maxey -  Word MVP

My web sitehttp://gregmaxey.mvps.org
Word MVP web sitehttp://word.mvps.org

Thanks for the answers so far, I really appreciate it. There was a
question about this code:
With ActiveDocument.Paragraphs(p).Range
ActiveDocument.Range(.Start, .End - 1).Select
End With

O.k., maybe it is just my lack of knowledge. I have to convert the
Word document into xml. Therefore I have to insert xml tags into the
text. I use the methods insertbefore and insertafter of the selection
object. But if I select the whole paragraph and do insertafter, the
text is inserted behind the vbCR, at the beginning of the next
paragraph. Which is not what I want. Therefore I select the text of
the paragraph minus 1 character. Then Selection.insertafter inserts
the text before the vbCR.

I have to take care of many other things. When a paragraph is the
first one with a list style, I have to insert an appropriate list tag.
After the last list item paragraph I have to close the list tag again.

In tables I have to not only enclose the paragraphs/cells in td tags,
but I have to encolse the rows in tr tags and the whole table in a
table tag.

Etc. pp.

My method of selecting all but the last character (paragraph end,
table cell end), and then using insertbefore and insertafter was the
oly one I came up with. But if you have any better suggestions I'd be
very glad.

Best regards,

Christian
 
G

Greg Maxey

Christain,

I suppose it is a nit, but I try to always use the range object and avoid
selecting things whenever possible. Perhaps this will do:

Sub ScratchMacro()
Dim oStrRange As Range
Dim StartTime As Single
Dim aPara As Range
StartTime = Timer
Set oStrRange = ActiveDocument.StoryRanges(wdMainTextStory)
Set aPara = oStrRange.Paragraphs(1).Range
With aPara
Do
Select Case aPara.Style
Case "Format 1"
.InsertBefore "<tag1>"
.MoveEnd wdCharacter, -1
.InsertAfter "</tag1>"
.Collapse wdCollapseEnd
.Move wdCharacter, 1
Case "Format 2"
.InsertBefore "<tag2>"
.MoveEnd wdCharacter, -1
.InsertAfter "</tag2>"
.Collapse wdCollapseEnd
.Move wdCharacter, 1
Case Else
.Collapse wdCollapseEnd
End Select
.MoveEnd wdParagraph, 1
Loop Until .End = oStrRange.End And Len(.Text) = 1
End With
Set aPara = Nothing
MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
End Sub
 
M

Manfred F

hi Christian,

I made some experiences with W2003 and large documents. One was that
iteration with
for each myPara in myDoc.Paragraphs
was much faster than using the index
for i = 1 to myDoc.Paragraphs.Count.

Another general experience was not to use the selection, but ranges instead.
Setting Application.ScreenUpdating = false may also help as well as
..ShowPicturePlaceHolders = True.
For long documents, the execution time of a macro usually increases
disproportionately, e. g. t(x) = k * x * x.

Regards,
Manfred
 
M

Manfred F

Hi,
one more observation: it will help to save the document every now and then.

Regards,
Manfred
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top