Hi Bear
Good questions! And the answers, in the end are "because someone at
Microsoft just did it that way".
QUESTION 1
There are lots of different ways of laying out code, especially code to find
text in a Word document. So I've re-arranged this a bit to make it easier to
see what's going on. And I've added voluminous comments. Sadly, Microsoft's
example code never explicitly establishes its variables. It's worth knowing
that the myStoryRange in the following is a Range object. One really should
create the variable explicitly, as I've done here.
Sub FindStuff
'Declare our variable
Dim myStoryRange As Range
'Before the next bit of code would work, we have to set the myStoryRange to
something
'(In the original, it cycles through all the StoryRanges)
Set myStoryRange = ActiveDocument.StoryRanges.Item(wdMainTextStory)
'Use myStoryRange (which is the main text story) and do stuff with Finding
With myStoryRange.Find
'Identify what to find
.Text = "Microsoft Word"
'Identify whether to search top-to-bottom or bottom-to-top
.Forward = True
'Tell Word what to do when it's finished searching. Specifically:
'(from the help file) what happens if the search begins at a point
'other than the beginning of the document and the end of the document
'is reached (or vice versa if Forward is set to False) or if the search
'text isn't found in the specified selection or range.
'
'The wdFindContinue setting is the default. So in Microsoft's code
'example they could omit it. That's fine for computers, but we
'humans might like to know what's going on.
'
'The .Wrap property works like the prompt you get in the UI if
'you select a range and do a search-and-replace within the range.
'Word asks if you want to continue searching in the rest of the
document.
'
'For what it's worth, if you want to restrict your search to a specific
'range, choose .Wrap = wdFindStop.
'
'So, we tell Word to keep searching after this Find.
'
.Wrap = wdFindContinue
'Go see if you can find anything
.Execute
'If Word found the text, then the myStoryRange object (which is
'just a Range object) is now re-assigned to the range where
'Word found the text it was looking for.
'
'However, if Word did not find the text, then myStoryRange
'is the same as it ever was.
'
'That's just how it works. The VBA help file explains much of this.
'We haven't yet looked to see if Word found the text.
'We can detect that using myStoryRange.Find.Found.
'If that is true, then Word found our text.
'If Word reported that it found something, then do this stuff.
While .Found
'If we found our text, then myStoryRange has been re-assigned
'to the text we found. Make it Italic.
myStoryRange.Italic = True
'Quick reminder:
'The .Forward setting is still True.
'The .Wrap setting is still wdFindContinue
'So, if we haven't hit the end of the document, Word will
'keep looking in the document.
'Go see if you can find another instance of our text
.Execute
'And if Word finds another instance of our text, then
'.Found will be true
'and myStoryRange will have been re-assigned to the
'newly-found text.
'So, if .Found is true, we'll loop here.
'If .Found is false, Word will kick us out of the loop
'and we can go home.
Wend
End With
EndSub
QUESTION 2
Here's an illustrated version of code to cycle through StoryRanges. I've
used a separate variable here for the 'inner' story ranges, where Microsoft
only uses one. And I've tried to make some things more explicit - it's not
necessarily good programming practice, it's just designed for illustration.
And I will count myself as having succeeded if, after working through this,
you no longer think that "While Not (myStoryRange.NextStoryRange Is
Nothing)" is Odd<g>.
Sub CycleThroughStoryRanges()
Dim myStoryRange As Range
Dim mySubRange As Range
'Go through every StoryRange (there are exactly 17 of them
'in Word 2003)
For Each myStoryRange In ActiveDocument.StoryRanges
'Do some stuff to this myStoryRange object
If myStoryRange.Paragraphs.Count > 0 Then
MsgBox myStoryRange.Paragraphs(1).Range.Text
End If
'But some stories have 'followers'. Eg if the document has more than
'one section, there may be many even page headers in the document.
'And we want to cycle through them all.
'Trap an error if the .NextStoryRange doesn't exist.
'For example, if myStoryRange is the even headers story, then there
might
'not be a Next even header. And the VBA Help for NextStoryRange explains
'that when myStoryRange is (eg) the footnotes story, then
.NextStoryRagne
'will always return Nothing.
On Error Resume Next
Set mySubRange = myStoryRange.NextStoryRange
On Error GoTo 0
If mySubRange Is Nothing Then
'There is no 'next' story - so if myStoryRange were, say,
'an even pages header, then there is no next even pages
'header. Or maybe, eg, myStoryRange is the footnotes, and
'it has no .NextStoryRange. So we can give up and go on.
Else
'We're here because mySubRange is *not* a Nothing
'While we continue to have more than Nothing, do this stuff
While Not (mySubRange Is Nothing)
'Do some stuff to this 'follower' range
If myStoryRange.Paragraphs.Count > 0 Then
MsgBox mySubRange.Paragraphs(1).Range.Text
End If
'See if we can find yet another 'follower' range
'(eg the next even header)
On Error Resume Next
Set mySubRange = mySubRange.NextStoryRange
On Error GoTo 0
'If we've found another 'follower' range (eg another
'even pages header), then we'll loop here.
'Otherwise, Word will kick us out of this inner loop
'and we'll go on to the next (top-level) myStoryRange.
Wend
End If
Next myStoryRange
End Sub

Signature
Hope this helps.
Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
> Adreas and Shauna:
>
[quoted text clipped - 40 lines]
>
> Bear
Bear - 28 Jun 2007 14:38 GMT
Shauna:
Thanks for your efforts. I'm not sure you've done more than beautifully
illuminate the odd nature of the DOM and VBA's interaction with it. But I'll
reread your code a few times to make sure I'm getting your points.
I DID get a new perspective on story ranges. Tell me if any of this is
wrong...
When you say of story ranges "there are exactly 17 of them in Word 2003" I
think you mean to say that there are 17 types of story range. The might be
any number of story ranges in a given document?
For whatever reason, "For Eaching" through the story range collection only
yields the first story range of each type, so the "inner" loop with the test
for Is Nothing is needed to process subsequent story ranges within a given
type.
Bear

Signature
Windows XP, Word 2000
Shauna Kelly - 30 Jun 2007 04:45 GMT
Hi
You have it exactly right--at least as I understand it.
You can see the 17 types if you look in VBA help under the Item Method for
the StoryRanges object. That lists 11 of them. But if you type
ActiveDocument.StoryRanges.Item( into the VBE, the intellisense lists 17 of
them. And the object browser lists 17.
I think that the apparently convoluted nature of the StoryRanges is because
(for example) a document has exactly one main story, it might or might not
have comments, and it might have any number of different headers and
footers.
Hope this helps.
Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
> Shauna:
>
[quoted text clipped - 17 lines]
>
> Bear
andreas - 01 Jul 2007 09:13 GMT
On 30 Jun., 05:45, "Shauna Kelly"
<ShaunaKe...@SendNoSpamToShaunaKelly.com> wrote:
> Hi
>
[quoted text clipped - 39 lines]
>
> - Zitierten Text anzeigen -
Shauna and Bear,
great comments from both of you. Very helpful. Thank you so much.
Regards,
Andreas