Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Word Macro to Insert Page Break 1

Status
Not open for further replies.

pgaec

Programmer
Aug 4, 2003
161
AU
Hello all


I have a word document that has

- two column layout
- a table that has header repeating on all pages (and allow row breaking between pages turned OFF)

The document has about 40 pages.

I would like to loop through the document page by page, and add a section break at the end of each page (so that I can have a different header on every page)

I tried to do this:

Code:
For i = 1 To Selection.Information(wdNumberOfPagesInDocument)

  Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Name:=CStr(i)

  ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument


  ActiveDocument.Bookmarks("\page").Range.Select

  Selection.InsertBreak Type:=wdSectionBreakContinuous

Next

But this results in 40 section breaks at the start of page 1.

I guess that

Code:
  ActiveDocument.Bookmarks("\page").Range.Select

selects the entire document instead of the current page.

Any ideas on how to achieve what I want?
 
I am developing something that looks like a yellow pages kind of document.

On odd pages, I want to display the first entry of the page in the header.

On even pages, I want to display the last entry of the page in the header.

Let me know if this doesn't make sense and I can post screenshots.
 
And besides, I have other reasons to write a macro to loop through the document page by page.

i.e, every entry in the table has a sequential number associated with it.

ie.,
Apple 1
Ball 2
etc....


I achieve this by adding a field to each row

Apple {SEQ test}
Ball {SEQ test}

I want the sequence to restart from 1 on every page.

So I would like a macro to go through each page and do this:

Code:
Sub aA()
  
For i = 1 To Selection.Information(wdNumberOfPagesInDocument)
  
  Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Name:=CStr(i)
  
  ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
  
  ActiveDocument.Bookmarks("\page").Range.Select
 
   
  If Selection.Fields.Count > 0 Then
     Selection.Fields(1).Code.Text = Selection.Fields(1).Code.Text & " \r1"
  End If

Next


ActiveDocument.Fields.Update 
 
End Sub

The above code doesn't work as it always the entire document instead of selecting the document page by page.


 
On odd pages, I want to display the first entry of the page in the header.

On even pages, I want to display the last entry of the page in the header.

Look at the STYLEREF Field for this - and use different Odd and Even page headers.

Enjoy,
Tony

------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.

I'm working (slowly) on my own website
 
Yeah. I thought about that but

And besides, I have other reasons to write a macro to loop through the document page by page.

So ideally I would like a macro to loop through the document page by page. Any ideas.
 
Hi pgaec ,

I agree with Tony: the correct use of different odd/even pages, coupled with a STYLEREF field should do what you want. You could even do it without a different odd/even page setup if you coded an IF test in the header/footer to apply a STYLEREF field with the appropriate switches for odd vs even pages. Either approach makes the document far easier to maintain than forcing page breaks at the end of each page - after all, something as simple as a change in printers, print drivers and even print driver settings can mess up all your lovely page breaks.

As for a macro to loop through the pages, try something based on:
Code:
Sub PageLoopDemo()
Dim oPg As Range, i As Integer
With ActiveDocument
  For i = 1 To .Range.Information(wdActiveEndPageNumber)
    Set oPg = .GoTo(What:=wdGoToPage, Name:=i)
    Set oPg = oPg.GoTo(What:=wdGoToBookmark, Name:="\page")
    MsgBox "Page: " & i & vbCrLf & _
      "First Word: " & oPg.Words.First & vbCrLf & _
      "Last Word: " & oPg.Words.Last
  Next
End With
End Sub


Cheers
[MS MVP - Word]
 
macroprod,

Thanks. But your macro produces the same result as mine.

Code:
    Set oPg = .GoTo(What:=wdGoToPage, Name:=i)

Does not loop through all pages - but instead it gets the entire document as page 1.

I dont think there is nothing wrong with your macro, but there is something funny with my document. Have a look and advise me what to do.

My document can be found at

 
Hi Pari Gandhi,

OK, so you're working on an EF054 (Division Finder)for the Australian Electoral Commission? I thought the AEC was doing away with these and moving over to a PDA-based system.

The macro I posted works fine. If you run it, you'll see that it reports a different first word for each page. It's not reporting a 'word' as such for the last word, because what it's finding is the end-of-row cell marker instead.

With your current document structure, you should be aware that, if you do insert page breaks at the end of each page, you'll also need to re-insert the table heading row on each new page thus created.

Also, for the SEQ fields, I believe you should force each to have 4? digits, padded as necessary with leading 0s. For this, you'd re-code the fields as: {SEQ lo \# 0000}



Cheers
[MS MVP - Word]
 
macropod,

I am not sure what I am doing wrong. But your macro results in the following message box for all 4 pages.

---------------------------
Microsoft Word
---------------------------
Page: 2

First Word:

Last Word:

---------------------------
OK
---------------------------

I am using Office 2007 BTW.
 
Hi Pari Gandhi,

Running Word 2007 (SP2) with the code I posted before, I get:

Page: 1
First Word:
Last Word:

Page: 2
First Word: Bakers
Last Word:

Page: 3
First Word: Biarra
Last Word:

Page: 4
First Word: Bowenville
Last Word:

In any event, for what you're trying to do, you'd probably need something closer to:
Code:
Sub PageLoopDemo()
Dim oPg As Range, i As Integer
With ActiveDocument
  For i = 1 To .Range.Information(wdActiveEndPageNumber)
    Set oPg = .GoTo(What:=wdGoToPage, Name:=i)
    Set oPg = oPg.GoTo(What:=wdGoToBookmark, Name:="\page")
    If oPg.Cells(1).Range = oPg.Tables(1).Range.Cells(1).Range Then oPg.MoveStart Unit:=wdCell, Count:=1
    MsgBox "Page: " & i & vbCrLf & _
      "First Cell, First Word: " & Trim(Replace(Split(oPg.Cells(1).Range.Text, vbTab)(0), vbCr, "")) & vbCrLf & _
      "Last Cell, First Word: " & Trim(Replace(Split(oPg.Cells(oPg.Cells.Count).Range.Text, vbTab)(0), vbCr, ""))
  Next
End With
End Sub

Please keep in mind, though, that what you're trying to do is still best done with a STYLEREF field.



Cheers
[MS MVP - Word]
 
Hi macropod,

In my case, your macro results in the following:

Code:
---------------------------
Microsoft Word
---------------------------
Page: 1

First Cell, First Word: Abbeywood

Last Cell, First Word: Bushland Beach
---------------------------
OK   
---------------------------

---------------------------
Microsoft Word
---------------------------
Page: 2

First Cell, First Word: Abbeywood

Last Cell, First Word: Bushland Beach
---------------------------
OK   
---------------------------

etc...

I am running SP1 - I am not sure whether that makes the difference or not.


Thanks for your help.

There are two issues I would like to solve here:

(a) How do I go about using the STYLEREF to work out the first / last field.

While generating the document, do I need to set the style for all fields to say "List Paragraph" and then, in my header, do something like:

Insert > Quick Parts > Fields > StyleRef > List Paragraph

Is that how I should proceed? Or am I on the wrong path?

(b) As mentioned earlier, I have a sequence {SEQ lo} - I want the sequence to restart from 1 on each page.

To achieve this, I tried

Code:
For i = 1 To .Range.Information(wdActiveEndPageNumber) 
    Set oPg = .GoTo(What:=wdGoToPage, Name:=i)
    Set oPg = oPg.GoTo(What:=wdGoToBookmark, Name:="\page")
    If oPg.Fields.Count > 0 Then
        oPg.Fields(1).Code.Text = oPg.Fields(1).Code.Text & " \r1"
    End If
  Next

But this is not giving me the correct results (for some reason, oPg.Fields(1) always selects the first field in the document, not the first field in the current page) - Again I think this *may* work in SP2 - I am not sure, but it does not work for me in SP1. Any ideas on this? Or is there a better way to do this?


 
Hi Pari Gandhi,

To use the STYLEREF fields you could run the following macro, to apply a 'HeadRef' character style to the
locality name in each cell in your file:
Code:
Sub StyleRefSetup()
Dim i As Integer, oRng As Range
Application.ScreenUpdating = False
With ActiveDocument.Tables(1).Range
  For i = 2 To .Rows.Count
    Set oRng = .Cells(i).Range.Characters.First
    oRng.MoveEnd wdCharacter, Len(Trim(Replace(Split(.Cells(i).Range.Text, vbTab)(0), vbCr, ""))) - 1
    oRng.Style = "HeadRef"
  Next
End With
Application.ScreenUpdating = True
End Sub
Then, in the page header, you can insert two fields:
Code:
{IF{=MOD({PAGE},2)}= 1 {STYLEREF "HeadRef"}}
and
Code:
{IF{=MOD({PAGE},2)}= 0 "{STYLEREF "HeadRef" \l}"}
However, you're going to have problems with the Ref #s if you want them to re-start on each page. It could be managed if your table had a separate column for the Ref #s, corresponding to each entry. Where you've got split localities as in Aldershot, for example, you'd need a separate table row for each locality. Once you've done that, you could replace the SEQ fields with the following rather complicated field construction in every row, including the header row:
Code:
{={IF{SEQ Row}= 1 "{SET LastPage 0}{SET LastRow 0}0" {IF{PAGE}= LastPage {=COUNT(ABOVE)-LastRow+({PAGE}>1)} "{SET LastRow {=COUNT(ABOVE)}}1{SET LastPage {PAGE}}"}} \# "00;;"}
Alternatively, you could do away with the numbering fields altogether and simply number the lines via a macro. If you do this, though, you're back to the same printer/driver issues I referred to earlier.

Note: The field brace pairs (ie '{ }') for the above examples are created via Ctrl-F9 - you can't simply type them or copy & paste them from this message.


Cheers
[MS MVP - Word]
 
macroprod

That was very helpful.

Few things I would like to point out:

The document is generated by a C# program and I have full control over what/how fields get inserted into the table cells.

i.e, the code that inserts the locality table cells looks like this:

- Add a table cell
- Set the paragraph styles for the table cell
- Add the locality text with the "HeadRef" style
- Add tabchar; Add the division name text
- Add tabchar; Add {SEQ lo}
- If the locality has children, add them

Therefore I did not use the StyleRefSetup macro , but instead set the style for the localities during the document generation itself.

Your STYLEREF header macro worked like a charm. Thank you very much for it.

Regarding the sequence number problem, I haven't tried your suggestion yet - But as I said, I have good control over the elements inserted into the table cell. So, I was wondering whether I can modify the document generation code to say something like:

If locality has no children (sub localities) , then display as:

Code:
Locality              Division             {SEQ lo}

If locality has siblings (sub localities), then display as
Code:
Locality                
           
1. Sibling 1          Division   {Complex SEQ here}

                        OR    
2. Sibling 2          Division   {Complex SEQ here}

Would it be simpler, If i did the above instead of putting the SEQ number in its own table cell?

I would need some assistance from you in setting / understanding the complex SEQ up as honestly when I googled up for "LastPage" / "LastRow" / "COUNT(ABOVE)" functions - I got no useful results. I may dig into the MSDN further to understand what they do.


 
Hi Pari Gandhi,

Whilst I agree that the use of a simple SEQ field is useful, it doesn't facilitate the automatic re-start of the numbering on each page. If those driving the project are amenable, you could, of course, have a continuous numbering series instead of re-starting on each page. AFAIK, that wouldn't compromise the way the Division Finder refernces are used.

Whilst the SEQ field approach alose works fine with split locailites in the same cell, the field formula I posted won't. As for the "LastPage" and "LastRow" variables, they're simply bookmark names assigned via the SET fields. You should find the "COUNT(ABOVE)" function in Word's Help file.


Cheers
[MS MVP - Word]
 
Hi macropod

The Release Notes for Office 2007 SP2 mention that the following bug

When you work with tables that have repeating header rows on pages that contain columns, the pointer or the selection is not visible while you are editing the part of the table that is located on the first page.

was fixed in SP2.

That would explain why your macro was producing different output in SP1.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top