2
votes

I have found this code online that does exactly what I would expect, however I am looking for a way to keep the header and footer. Right now it only takes the small main body and removes the header and footer when doing its copying into a new document. The reason I don't do this manually is because there are well over 200 pages. Looking through the code I figured it might have something to do with expanding the range it reads through.

Sub SplitIntoPages()
Dim docMultiple As Document
Dim docSingle As Document
Dim rngPage As Range
Dim iCurrentPage As Integer
Dim iPageCount As Integer
Dim strNewFileName As String
Application.ScreenUpdating = False 'Makes the code run faster and reduces screen _
flicker a bit.
Set docMultiple = ActiveDocument 'Work on the active document _
(the one currently containing the Selection)
Set rngPage = docMultiple.Range 'instantiate the range object
iCurrentPage = 1
'get the document's page count
iPageCount = docMultiple.Content.ComputeStatistics(wdStatisticPages)
Do Until iCurrentPage > iPageCount
If iCurrentPage = iPageCount Then
rngPage.End = ActiveDocument.Range.End 'last page (there won't be a next page)
Else
'Find the beginning of the next page
'Must use the Selection object. The Range.Goto method will not work on a page
Selection.GoTo wdGoToPage, wdGoToAbsolute, iCurrentPage + 1
'Set the end of the range to the point between the pages
rngPage.End = Selection.Start
End If
rngPage.Copy 'copy the page into the Windows clipboard
Set docSingle = Documents.Add 'create a new document
docSingle.Range.Paste 'paste the clipboard contents to the new document
'remove any manual page break to prevent a second blank
docSingle.Range.Find.Execute Findtext:="^m", ReplaceWith:=""
'build a new sequentially-numbered file name based on the original multi-paged file name and path
strNewFileName = Replace(docMultiple.FullName, ".doc", "_" & Right$("000" & iCurrentPage, 4) & ".doc")
docSingle.SaveAs strNewFileName 'save the new single-paged document
iCurrentPage = iCurrentPage + 1 'move to the next page
docSingle.Close 'close the new document
rngPage.Collapse wdCollapseEnd 'go to the next page
Loop 'go to the top of the do loop
Application.ScreenUpdating = True 'restore the screen updating
'Destroy the objects.
Set docMultiple = Nothing
Set docSingle = Nothing
Set rngPage = Nothing
End Sub

What I have: Consistent header/footer, with variable main body.

What I expect: VBA executes and breaks each page into a new document.

What happens: VBA breaks each main body into a new document and tosses the header/footer.

1

1 Answers

1
votes

A document's header/footer belong to the section break, not to individual pages. So copying page content cannot/will not include the header/footer.

One approach would be to

  • get the page count
  • set up a loop based on the page count
  • remove all content except the page that should be retained
  • save the file, close it, re-open the file and repeat the removal for the next page

Another possibility would be to also duplicate the header/footer in the new document. I've altered your code (and formatted it!) with a couple of lines that do this. I'm assuming that there are only "primary" headers and footers in the source document - no first page or even page ones.

    'get the header
    docSingle.Sections(1).Headers(wdHeaderFooterPrimary).Range.FormattedText = _
        rngPage.Sections(1).Headers(wdHeaderFooterPrimary).Range.FormattedText
    'get the footer
    docSingle.Sections(1).Footers(wdHeaderFooterPrimary).Range.FormattedText = _
        rngPage.Sections(1).Footers(wdHeaderFooterPrimary).Range.FormattedText

Rather than using copy/paste this code uses the Range.FormattedText property to transfer the data. Generally, it's better to avoid the clipboard and go directly, although there can be exceptions to the rule... If there are multiple sections in the source document this code should pick up the header/footer of the section for the page being copied, which is why it uses rngPage rather than docMultiple for the source.

Sub SplitIntoPages()
    Dim docMultiple As Document
    Dim docSingle As Document
    Dim rngPage As Range
    Dim iCurrentPage As Integer
    Dim iPageCount As Integer
    Dim strNewFileName As String

    Application.ScreenUpdating = False 'Makes the code run faster and reduces screen _
    flicker a bit.
    Set docMultiple = ActiveDocument 'Work on the active document _
    (the one currently containing the Selection)
    Set rngPage = docMultiple.content 'instantiate the range object
    iCurrentPage = 1

    'get the document's page count
    iPageCount = docMultiple.content.ComputeStatistics(wdStatisticPages)
    Do Until iCurrentPage > iPageCount
        If iCurrentPage = iPageCount Then
            rngPage.End = ActiveDocument.Range.End 'last page (there won't be a next page)
        Else
            'Find the beginning of the next page
            'Must use the Selection object. The Range.Goto method will not work on a page
            Selection.GoTo wdGoToPage, wdGoToAbsolute, iCurrentPage + 1
            'Set the end of the range to the point between the pages
            rngPage.End = Selection.Start
        End If
        'rngPage.Copy 'copy the page into the Windows clipboard

        Set docSingle = Documents.Add 'create a new document
        docSingle.content.FormattedText = rngPage.FormattedText 'carry over the page to the new document
        'remove any manual page break to prevent a second blank
        docSingle.Range.Find.Execute findText:="^m", ReplaceWith:=""
        'get the header
        docSingle.Sections(1).Headers(wdHeaderFooterPrimary).Range.FormattedText = _
            rngPage.Sections(1).Headers(wdHeaderFooterPrimary).Range.FormattedText
        'get the footer
        docSingle.Sections(1).Footers(wdHeaderFooterPrimary).Range.FormattedText = _
            rngPage.Sections(1).Footers(wdHeaderFooterPrimary).Range.FormattedText

        'build a new sequentially-numbered file name based on the original multi-paged file name and path
        strNewFileName = Replace(docMultiple.FullName, ".doc", "_" & Right$("000" & iCurrentPage, 4) & ".doc")
        docSingle.SaveAs strNewFileName 'save the new single-paged document

        iCurrentPage = iCurrentPage + 1 'move to the next page
        docSingle.Close 'close the new document
        Set docSingle = Nothing 'release for the next iteration
        Set rngPage = Nothing
        rngPage.Collapse wdCollapseEnd 'go to the next page
    Loop 'go to the top of the do loop
    Application.ScreenUpdating = True 'restore the screen updating
    'Destroy the objects.
    Set docMultiple = Nothing
End Sub