G'day Jay Freedman <JayFreedman@discussions.microsoft.com>,
What is even faster is to use something like this
Collapse mypara to end
Extend to next para end
if one char then end of doc
it maintains a LINEAR access speed, unlike the for each which has to
dynamically calculate the next para FROM THE START.
On documents <1200 paras this makes a little difference, on large
documents it makes a HUGE difference - like HOURS quicker. 1200 real
world paras seems to be the rough point at which you can definitively
see a major slowdown in code execution iterating collections.
My reverse engineering of this thus says Word has some sort of buffer
for content, it is very large, but finite. So for 1200 paras we have
to also keep reloading the correct buffer after say 1024 paragraphs,
thus it only takes a few hundred iterations of this (1025-1200) to
show up on your performance graphs as a steeper gradient at this
point.
This makes business sense as it enables faster document processing for
the much more frequently occuring smaller documents, whilst still
allowing for the rarer large documents to exist. 80/20 right?
This has also been platform independant - in so far as different CPUs
and memory sizes on the host system made no difference to the
findings.
So, by doing it the heretical way, the number of paragraphs scanned
for their content to 'serialise' them is equivalent to the paragraphs
count, instead of the factorial of the count as is the case with any
dynamic collection based method (chars / paras / whatever).
Dynamic method:
This is my #1 trade secret for writing ultra fast macros. Don't forget
it! :-) It only takes about 30 mins for a reasonably competent user to
do a basic check of these assertions if they are so inclined.
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Jay Freedman reckoned:
>Hi Greg,
>
[quoted text clipped - 15 lines]
>the parameter. I've found that accessing the Characters collection of a range
>is far slower than anything else.
Greg Maxey - 31 Dec 2004 02:50 GMT
Steve
Do you mean something like this:
Sub Test1()
Dim myPara As Range
Set myPara = ActiveDocument.Paragraphs(1).Range
Do Until Len(myPara) = 1
If Left(myPara.Text, 1) <> " " Then
myPara.Style = "Body Text"
End If
myPara.Collapse Direction:=wdCollapseEnd
myPara.Expand Unit:=wdParagraph
myPara.Select
Loop
End Sub
The only way I could figure out how to break out of the loop was an empty
paragraph at the end of the document and then the Len(myPara) condition. I
know that there has to be a better way, but I am stumped.

Signature
Greg Maxey/Word MVP
A Peer in Peer to Peer Support
> G'day Jay Freedman <JayFreedman@discussions.microsoft.com>,
>
[quoted text clipped - 65 lines]
>> temporary variable for the parameter. I've found that accessing the
>> Characters collection of a range is far slower than anything else.
Greg Maxey - 31 Dec 2004 03:01 GMT
Steve,
I cobbled this together. Does it defeat the speed advantage you proposed?
Sub Test1()
Dim myPara As Range
Dim i As Long
Set myPara = ActiveDocument.Paragraphs(1).Range
i = 0
Do
i = i + 1
If Left(myPara.Text, 1) <> " " Then
myPara.Style = "Body Text"
End If
myPara.Collapse Direction:=wdCollapseEnd
myPara.Expand Unit:=wdParagraph
Loop Until i = ActiveDocument.Paragraphs.Count
End Sub

Signature
Greg Maxey/Word MVP
A Peer in Peer to Peer Support
> Steve
>
[quoted text clipped - 87 lines]
>>> temporary variable for the parameter. I've found that accessing the
>>> Characters collection of a range is far slower than anything else.
Word Heretic - 31 Dec 2004 06:22 GMT
G'day "Greg Maxey" <gmaxey@mvps.OscarRomeoGolf>,
Yes - it does. However, it is no good for when you are EDITING content
and the length or number of paragraphs may change. Which is why your
base 'marker' has to be a range. I have sent an article submission
directly to you in explanation.
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Greg Maxey reckoned:
>Steve,
>
[quoted text clipped - 14 lines]
>Loop Until i = ActiveDocument.Paragraphs.Count
>End Sub
Greg Maxey - 31 Dec 2004 03:04 GMT
P.S.
I am not yet a reasonably competent user.

Signature
Greg Maxey/Word MVP
A Peer in Peer to Peer Support
> Steve
>
[quoted text clipped - 87 lines]
>>> temporary variable for the parameter. I've found that accessing the
>>> Characters collection of a range is far slower than anything else.
Word Heretic - 31 Dec 2004 06:22 GMT
G'day "Greg Maxey" <gmaxey@mvps.OscarRomeoGolf>,
At least you are making considerable progress and efforts :-) It is
the next best thing.
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Greg Maxey reckoned:
>P.S.
>
>I am not yet a reasonably competent user.
Word Heretic - 31 Dec 2004 06:25 GMT
G'day "Greg Maxey" <gmaxey@mvps.OscarRomeoGolf>,
I was misleading in my len=1, any blank para will stop that loop. I
test the range end against the current storyrange end.
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Greg Maxey reckoned:
>Steve
>
[quoted text clipped - 15 lines]
>paragraph at the end of the document and then the Len(myPara) condition. I
>know that there has to be a better way, but I am stumped.
Greg Maxey - 31 Dec 2004 04:59 GMT
Well I must be missing something Steve. I tried both of my attempts to use
your suggestions on a several thousand paragraph document and the result was
an order of magnitude slower. I suppose it has something to do with my exit
strategy.

Signature
Greg Maxey/Word MVP
A Peer in Peer to Peer Support
> G'day Jay Freedman <JayFreedman@discussions.microsoft.com>,
>
[quoted text clipped - 65 lines]
>> temporary variable for the parameter. I've found that accessing the
>> Characters collection of a range is far slower than anything else.
Word Heretic - 31 Dec 2004 06:25 GMT
G'day "Greg Maxey" <gmaxey@mvps.OscarRomeoGolf>,
See previous reply.
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Greg Maxey reckoned:
>Well I must be missing something Steve. I tried both of my attempts to use
>your suggestions on a several thousand paragraph document and the result was
>an order of magnitude slower. I suppose it has something to do with my exit
>strategy.
Greg Maxey - 31 Dec 2004 12:17 GMT
Steve,
I see your point. I ran the following two macros on a document containing
100,000 single line paragraphs. Your method was over 20% faster:
Sub UsualWay()
'Time to process 100,000 single line paragraphs 85.79 seconds
Dim StartTime As Single
Dim aPara As Paragraph
StartTime = Timer
With ActiveDocument.StoryRanges(wdMainTextStory)
For Each aPara In .Paragraphs
aPara.Range.HighlightColorIndex = HColor
Select Case HColor
Case wdRed
HColor = wdNoHighlight '0
Case wdNoHighlight
HColor = wdBlue '2
Case wdBlue
HColor = wdRed '6
End Select
Next aPara
End With
Set aPara = Nothing
MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
End Sub
Public Sub FasterWay()
'Time to process 100,0000 single line paragraphs 69.45 seconds
Dim StartTime As Single
Dim aPara As Range
StartTime = Timer
With ActiveDocument.StoryRanges(wdMainTextStory)
Set aPara = .Paragraphs(1).Range
Do
aPara.HighlightColorIndex = HColor
Select Case HColor
Case wdRed
HColor = wdNoHighlight '0
Case wdNoHighlight
HColor = wdBlue '2
Case wdBlue
HColor = wdRed '6
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

Signature
Greg Maxey/Word MVP
A Peer in Peer to Peer Support
> G'day Jay Freedman <JayFreedman@discussions.microsoft.com>,
>
[quoted text clipped - 65 lines]
>> temporary variable for the parameter. I've found that accessing the
>> Characters collection of a range is far slower than anything else.
Word Heretic - 31 Dec 2004 15:03 GMT
G'day "Greg Maxey" <gmaxey@mvps.OscarRomeoGolf>,
I can assure Real Life documents are even more dramatic for the
reasons explained in the article :-)
By the way Greg - you have just demonstrated your competency as the
article claims a reasonably competent user can easily prove the
principles inside half an hour...
<evil grins>
We will learns ya!
Steve Hudson - Word Heretic
steve from wordheretic.com (Email replies require payment)
Without prejudice
Greg Maxey reckoned:
>Steve,
>
[quoted text clipped - 48 lines]
>
>End Sub