1
votes

Couldn't find the answer I was looking for.

I want to get the current page number String including its format.
For example: Some sections may have chapter identifier (1-1), some are in Roman style, etc..

My hope was to get the selection of the specific footer, then loop through the fields and get the Page field data (Output is the String I want).

So far as I can see, there is no option to loop through the footers of a given section, just get the general template and try working with it.
I'm aware of wdActiveEndAdjustedPageNumber from Selection.Range.Information, but it just gives me partial information.

Am I wrong? Is there a way to work with a specific footer I choose?
If not, can you guide me how to get the following data:

  • Closest chapter number value
  • Getting the page number value of a special format such as Roman, Alphabetical font (Meaning applying the page format on the wdActiveEndAdjustedPageNumber)

Thanks.

Edit for clarification:

  1. In my word template, the Heading 1 style creates the following header: Chapter 1, followed by Chapter 2 and so on.
    In page number format, there is an option to include the current Chapter value to the page number.
    For example: Assuming the following setup

    Page Number format
    will result with these pages in the { PAGE } field: 1-1, 1-2, 1-3, ... My goal is to somehow get this entire "value" for a specific page footer.
    Here is a code snippet which won't work properly:

    Sub getPageFieldInFooter()
    ' get current section number
    Dim sectionNum As Integer
    sectionNum = Selection.Range.Information(wdActiveEndSectionNumber)
    'select first page footer, loop through its fields and find Page field
    ActiveDocument.Sections(sectionNum).Footers(wdHeaderFooterPrimary).Range.Select
    Dim f As Field
    For Each f In Selection.Fields
        If f.Type = wdFieldPage Then
            ' do something with the page data
            MsgBox f.Data
        End If
    Next f
    End Sub
    

    The output of such a method is '1-1'
    The reason it won't work is because it can retrieve the first page only (or the second using wdHeaderFooterEvenPages).

  2. Same goes for Roman number format, or any other from that list.
    For the following page number settings, I wish to get the "value" in a specific footer.
    The code above will return the values for first or second page, and that's it. Roman Number format

Is there a way to access any footer in the document and perform my code example?
If not, how can I get the page number "value" for any footer I choose?
Hope this is clearer.

3

3 Answers

2
votes

The following is working for me, although I'm not certain how reliable it is. Apparently, if I query the Footer (or Header) of the current selection in the document it will return the information for the Footer (or Header) of that page.

Things get very complicated as soon as you start working with multiple sections and Different First Page. I've done some testing for that in the code below, but I wouldn't swear it's "production code". However, it should give you a starting place.

Sub GetFormattedPageNumberFromSelection()
    Dim sel As word.Selection
    Dim sec As word.Section
    Dim r As word.Range, rOriginal As word.Range
    Dim fld As word.Field
    Dim secCurrIndex As Long
    Dim sNoPageNumber As String

    Set sel = Selection
    If Not sel.InRange(sel.Document.content) Then Exit Sub

    Set sec = sel.Sections(1)
    If Not sec.Footers(wdHeaderFooterFirstPage).exists Then
        Set r = sec.Footers(wdHeaderFooterPrimary).Range
    Else
        Set r = sel.Range
        Set rOriginal = r.Duplicate
        secCurrIndex = sec.index
        If secCurrIndex <> 1 Then
            sel.GoToPrevious wdGoToPage
            If sel.Sections(1).index = secCurrIndex Then
                Set r = sec.Footers(wdHeaderFooterPrimary).Range
            Else
                Set r = sec.Footers(wdHeaderFooterFirstPage).Range
            End If
            rOriginal.Select 'return to original selection
        ElseIf r.Information(wdActiveEndPageNumber) = 1 Then
            Set r = sec.Footers(wdHeaderFooterFirstPage).Range
        Else
            Set r = sec.Footers(wdHeaderFooterPrimary).Range
        End If
    End If
    For Each fld In r.Fields
        sNoPageNumber = "No page number"
        If fld.Type = wdFieldPage Then
            Debug.Print fld.result
            sNoPageNumber = ""
            Exit For
        End If
    Next
    If Len(sNoPageNumber) > 0 Then Debug.Print sNoPageNumber
End Sub
2
votes

...and sometimes we don't see the simplest way.

Insert a Page field at the current selection, read the result, then delete it again:

Sub GetFormattedPageNumberFromSelection2()
    Dim rng As word.Range
    Dim fld As word.Field

    Set rng = Selection.Range
    Set fld = rng.Fields.Add(rng, wdFieldPage)
    Debug.Print fld.result
    fld.Delete
End Sub
1
votes

What you haven't told us is how you're 'choosing' the page you want the reference for. Assuming it's based in whatever page is selected/displayed, you could use something like the following for a page header:

Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range, Fld As Field
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
For Each Fld In Selection.HeaderFooter.Range.Fields
  If Fld.Type = wdFieldPage Then
    MsgBox Fld.Result
    Exit For
  End If
Next
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
Application.ScreenUpdating = True
End Sub

Unfortunately, wdSeekCurrentPageFooter returns the next page's footer!, so you can't use that for the current footer. The following, however, should work wherever the PAGE # field is located:

Sub Demo()
Application.ScreenUpdating = False
Dim i As Long, Fld As Field, bExit As Boolean: bExit = False
With ActiveWindow.ActivePane.Pages(Selection.Information(wdActiveEndAdjustedPageNumber))
  For i = 1 To .Rectangles.Count
    With .Rectangles(i).Range
      For Each Fld In .Fields
        If Fld.Type = wdFieldPage Then
          MsgBox Fld.Result
          bExit = True: Exit For
        End If
      Next
    End With
    If bExit = True Then Exit For
  Next
End With
Application.ScreenUpdating = True
End Sub