find do loop not working

Hi experts

I have the following code which is supposed to loop through my document, find my Heading 9 paragraphs and then pick up the section number, copy the first pager header to that section and then loop to the next Heading 9 in the document.

My problem is that it isn't looping - it seems to be stuck wanting to do the same Heading 9 the entire time. I see that when I loop through the code. If I run it - it hangs Word, obviously because it is stuck in the loop.

HELP!.
Private Sub ReplaceAppendixCoverPages()

    'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
    
    Set Thisdoc = ActiveDocument
    
    Dim myRange As Range
    Dim n As Integer
    
    With Thisdoc.Content.Find
        .ClearFormatting
        .Style = ("Heading 9")
        Do While .Execute(Forward:=True, Format:=True) = True
            With .Parent
                Set myRange = Selection.Range
                myRange.Select
                n = myRange.Information(wdActiveEndSectionNumber)
                Thisdoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                CopyCoverPage n
            End With
        Loop
    End With

End Sub

Open in new window

Fi69Asked:
Who is Participating?
 
GrahamSkanRetiredCommented:
Your second attempt walked through each Section and tested it for a heading 9 style, and it looks OK.

FYI here is a simplified version
Sub ReplaceAppendixCoverPages2()
    Dim sec As Section
    Dim n As Integer
    For Each sec In ActiveDocument.Sections
        With sec.Range.Find
            .Style = wdStyleHeading9
            If .Execute Then
                n = sec.Index
                sec.Headers(wdHeaderFooterFirstPage).LinkToPrevious = False
                sec.PageSetup.DifferentFirstPageHeaderFooter = True
                CopyCoverPage n
            End If
        End With
    Next sec
End Sub

Open in new window

0
 
dsineCommented:
Where are you navigating or moving to the next section in your code ?
0
 
n2fcCommented:
You SAY you to "go to the next heading 9"...

You NEED to actually CODE an increment to DO that at the bottom of your loop!

It is NOT automatic!  That's why you stay on the same one!
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
Fi69Author Commented:
I thought I was by this bit

Set myRange = Selection.Range
myRange.Select

My understanding is that it is finding the Heading 9 paragraph, then I'm selecting it doing what I need to do, then the loop makes it go to the next heading 9.

Not correct?

0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
I have found that :
With Thisdoc.Content.Find
is the problem, because it will do the .execute starting from the same point again and again, so always find the same thing.
remove the with syntax (i know it would be nicer code...) and try that ...
0
 
dsineCommented:
If you want to iterate through the selection

Dim CurCell As Range
        For Each CurCell In Selection
             do something here
        Next CurCell
0
 
Fi69Author Commented:
Hi n2fc: your raising the same point as  dsine so obviously that's my error. How do I tell it to move on?
0
 
Fi69Author Commented:
dsine:

Hi dsine I suppose I could do for each paragraph in the activedocument, see if it is a heading 9 and then do what i need it to do, then move to the next, but it could be a really big document, so that's not desirable.

angelIII: sorry don't understand what you want me to do with the code?
0
 
GrahamSkanRetiredCommented:
Fi, in your loop, you set the range to the Selection (end selection to the range), and use that regardless of what the Find does.
0
 
GrahamSkanRetiredCommented:
I don't have a document set up to test it, but try this.
'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
    
    Set ThisDoc = ActiveDocument
    
    Dim myRange As Range
    Dim n As Integer
    Set myRange = ThisDoc.Range
    With myRange.Find
        .ClearFormatting
        .Style = "Heading 9"
        Do While .Execute(Forward:=True, Format:=True) = True
            With .parent
                n = myRange.Information(wdActiveEndSectionNumber)
                ThisDoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                CopyCoverPage n
            End With
        Loop
    End With

End Sub

Open in new window

0
 
Fi69Author Commented:
Hi Graham

That didn't work either. Still stuck doing the same heading over and over.
0
 
GrahamSkanRetiredCommented:
Not to clear about what your document looks like, so see if this helps
Private Sub ReplaceAppendixCoverPages()

'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
Dim ThisDoc As Document
    
    Dim myRange As Range
    Dim n As Integer
    
    Set ThisDoc = ActiveDocument
    Set myRange = ThisDoc.Range
    With myRange.Find
        .ClearFormatting
        .Style = "Heading 9"
        Do While .Execute(Forward:=True, Format:=True) = True
            With .parent
                n = myRange.Information(wdActiveEndSectionNumber)
                ThisDoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                MsgBox myRange.Text & " found in section " & n
            End With
        Loop
    End With

End Sub

Open in new window

0
 
Fi69Author Commented:
Nope that didn't work either. Gets stuck in loop.

I've changed the way I'm doing it. I think it's working. Lucky, I've only got a couple of strands of hair left.

What's your thoughts - practical approach?

Dim TotalSections As Integer
    Dim i As Integer
    Dim r As Range
    Dim n As Integer
    
    i = 1
    TotalSections = ActiveDocument.Sections.Count
    Set r = ActiveDocument.Range(Start:=ActiveDocument.Sections(i).Range.Start, End:=ActiveDocument.Sections(TotalSections).Range.End)
    
    Do While i <= TotalSections
        
        r.SetRange Start:=ActiveDocument.Sections(i).Range.Start, End:=ActiveDocument.Sections(TotalSections).Range.End
        r.Select
        
        With Selection.Find
            .ClearFormatting
            .Style = wdStyleHeading9
            .MatchWholeWord = False
            .MatchCase = False
'            .Forward = True
            If .Execute(FindText:="") Then
                n = Selection.Information(wdActiveEndSectionNumber)
                MsgBox n
                ActiveDocument.Sections(n).Headers(wdHeaderFooterFirstPage).linktoprevious = False
                ActiveDocument.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                CopyCoverPage n
                i = n + 1
            Else
                i = i + 1
            End If
        End With
    Loop

Open in new window

0
 
Fi69Author Commented:
Take that back. It was work before now it's not.  There goes those last few hairs...
0
 
GrahamSkanRetiredCommented:
I can't be sure, because I have probably not understood the problem well enough.

In my tests, the code in the second macro reported all the occurrences of Heading 9 text and the section numbers in which they were found.

Here is some simplified code to do the same thing
Private Sub ReplaceAppendixCoverPages()

    'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
    Dim ThisDoc As Document
    Dim myRange As Range
    Dim n As Integer
    
    Set ThisDoc = ActiveDocument
    Set myRange = ThisDoc.Range
    With myRange.Find
        .ClearFormatting
        .Style = "Heading 9"
        Do While .Execute(Forward:=True, Format:=True) = True
            n = myRange.Sections.First.Index
            ThisDoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
            MsgBox myRange.Text & " found in section " & n
        Loop
    End With

End Sub

Open in new window

0
 
Fi69Author Commented:
now it's working. I had to set the .forward to true.

Dim TotalSections As Integer
    Dim i As Integer
    Dim r As Range
    Dim n As Integer
    
    
    i = 1
    TotalSections = ActiveDocument.Sections.Count
    Set r = ActiveDocument.Range(Start:=ActiveDocument.Sections(i).Range.Start, End:=ActiveDocument.Sections(TotalSections).Range.End)
    
    Do While i <= TotalSections
        
        r.SetRange Start:=ActiveDocument.Sections(i).Range.Start, End:=ActiveDocument.Sections(TotalSections).Range.End
        r.Select
        
        With Selection.Find
            .ClearFormatting
            .Style = wdStyleHeading9
            .MatchWholeWord = False
            .MatchCase = False
            .Forward = True
            If .Execute(FindText:="") = True Then
                n = Selection.Information(wdActiveEndSectionNumber)
                MsgBox n
                ActiveDocument.Sections(n).Headers(wdHeaderFooterFirstPage).linktoprevious = False
                ActiveDocument.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                CopyCoverPage n
                i = n + 1
            Else
                i = i + 1
            End If
        End With
    Loop
    
 
    Set r = Nothing

Open in new window

0
 
GrahamSkanRetiredCommented:
Is it possible to post a sample document, so we can understand the problem better?
0
 
GrahamSkanRetiredCommented:
Because there is only one Selection object, Selection.Find will use the previous settings in that Word session.

Using a Range.Find can do the same in  the same macro, but the range objects are destroyed when the macro stops, so the specifying default settings, like .Forward = True are not usually necessary.
0
 
Fi69Author Commented:
Okay. I'm too scared to touch it now!
I'll post a sample doc shortly.
0
 
GrahamSkanRetiredCommented:
Sorry. That was only an explanation. Because you have switched to using the Selection.Find, I thought that I would tell you why is acts a little differently from a Range.Find.

If the code is working, you could leave it there, but if you do post the document, I'll see if I can tidy the code up a bit for your.
0
 
Fi69Author Commented:
Hi Graham

Okay, here is the sample doc. You'll see there are images in the header on page 1 (cover page).
That same set of images has to appear on the appendix pages (at the moment they're different). Appendices are Heading 9 style.
So what I was trying to do was find each occurrency of heading 9, make sure that the section header was set to different first page, and change then copy the header from page 1 (cover page) to the section header of where the Heading 9 appears (code below that gets called).

Thank you for looking at it!!!

 Sample-doc-ee.docx
Sub CopyCoverPage(iCover As Integer)

    Dim rng As Range
    Set ThisDoc = ActiveDocument
    Set rng = ThisDoc.Sections(iCover).Headers(wdHeaderFooterFirstPage).Range
    
    ThisDoc.Sections(1).Headers(wdHeaderFooterFirstPage).Range.Copy
    rng.Paste
    
    
End Sub

Open in new window

0
 
GrahamSkanRetiredCommented:
Ah, I see now.

Your problem was that some of the sections that contained a 'Heading 9' paragraph had more that one such paragraph, so it stayed copying and pasting on some of the sections several times, not appearing to progress.

This code uses a second integer variable (m) to check that we haven't done that section.

Private Sub ReplaceAppendixCoverPages()

    'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
    Dim ThisDoc As Document
    Dim myRange As Range
    Dim n As Integer
    Dim m As Integer
    
    Set ThisDoc = ActiveDocument
    Set myRange = ThisDoc.Range
    With myRange.Find
        .ClearFormatting
        .Style = "Heading 9"
        Do While .Execute
            n = myRange.Sections.First.Index
            If n > m Then
                ThisDoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                MsgBox myRange.Text & " found in section " & n
                CopyCoverPage n
            End If
            m = n
        Loop
    End With

End Sub

Open in new window

0
 
Fi69Author Commented:
Thank you, I'll test both of those.

With your second last response - what I'm noticing is that when the Heading 9 is applied to the paragraph the section break preceeding it holds the style, causing it to think the earlier section has a section 9 also when it doesn't.

For instance my actual heading 9 text is in section 10, but section 9 is being activated because the section break prior to the text is holding the style also. Hope that makes sense...
0
 
Fi69Author Commented:
Actually that's happening with both of those codes. Any suggestions on getting around that.
I suppose if the range was set to the end of the paragraph and then the section was determined from there? Not sure how to go about achieving that though...help!
0
 
Fi69Author Commented:
Okay, I think I've finally got it working nicely.
The end of the paragraph did not resolve the issue.
The problem is that the heading 9 is found on the section break preceeding the actual text. So as you mentioned earlier, it actually finds heading 9 twice - once on the actual section break, and then on the actual text.
So I've based this solution on testing to see if a section break is contained in the found text. see your modified code below.

Question: is there a better way to look for the section break? I just did a debug and used that character.. "^p" doesn't seem to work.


Private Sub ReplaceAppendixCoverPages()

    'goto each heading 9
    'make sure the page is a first page header
    'get the section number
    'replace the header with the cover page header
    
    Dim ThisDoc As Document
    Dim myRange As Range
    Dim n As Integer
    Dim m As Integer
    Dim l As Integer
    
    Set ThisDoc = ActiveDocument
    Set myRange = ThisDoc.Range
    With myRange.Find
        .ClearFormatting
        .Style = "Heading 9"
        Do While .Execute
            n = myRange.Sections.First.Index
            If FindString(myRange.Text, "") = True Then
                MsgBox "section" & n & " contains a section break, don't do this section"
            Else
                ThisDoc.Sections(n).PageSetup.DifferentFirstPageHeaderFooter = True
                ThisDoc.Sections(n).Headers(wdHeaderFooterFirstPage).linktoprevious = False
                MsgBox "Do section" & n
                CopyCoverPage n
            End If
        Loop
    End With


End Sub

Open in new window

0
 
GrahamSkanRetiredCommented:
The quick answer this morning in that ^s is used in Find to locate section breaks.
0
 
Fi69Author Commented:
Thanks for helping!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.