none
VBA & Word: Which Sections will be printed? RRS feed

  • Question

  • I have implemented the event DocumentBeforePrint with Word 2013.

    I've modified the backstage print view where the user can select a text (stamp) which will be inserted as a watermark and removed after the print has been done.

    In the event DocumentBeforePrint I would like to get the information what the user wants to print (All of the document, or only certain sections of it.) Because setting the watermark in the Footer of each Section takes up some time and I would like to narrow it down and insert the watermark only in the Section which will be printed.

    Thanks for any help! Martin

    Wednesday, December 17, 2014 7:33 AM

Answers

  • In that case, you'd probably need to use a DocumentBeforePrint macro, coded along the lines of:

    Private Sub wdApp_DocumentBeforePrint(ByVal Doc As Document, Cancel As Boolean)
    Dim StrPrn As String, StrRng As String
    'Retrieve the print parameters from the FilePrint Dialog
    With Application.Dialogs(wdDialogFilePrint)
        'If Print =
        'All, StrPrn = 0
        'Current Page, StrPrn = 2
        'Pages, StrPrn = 4
        StrPrn = .Range
        'If StrPrn = 4, then StrRng holds the range to be printed
        StrRng = .Pages
    End With
    Select Case StrPrn
      Case 0: StrRng = "1" & "-" & ActiveDocument.Sections.Count
      Case 2: StrRng = Selection.Sections.First.Index
      Case 4
        If InStr(StrRng, "p") > 0 Then
          MsgBox "Please specify only Section #s", vbExclamation
          Cancel = True
          Exit Sub
        End If
        StrRng = Replace(StrRng, "s", "")
    End Select
    StrRng = ParseNumberString(StrRng, ",", "-")
    'StrRng now holds an itemised list of Section #s for further processing
    MsgBox StrRng
    End Sub

    Function ParseNumberString(StrIn As String, strSS, strGS)
    Dim i As Long, j As Long, StrTmp As String, Arr As Variant
    Arr = Filter(Split(StrIn, strSS), strGS)
    For i = 0 To UBound(Arr)
      StrTmp = ""
      For j = Val(Arr(i)) To Split(Arr(i), strGS)(1)
        StrTmp = StrTmp & strSS & j
      Next
      StrIn = Replace(StrIn, Arr(i), Mid(StrTmp, 2))
    Next
    ParseNumberString = StrIn
    End Function

    To use code like this, see:
    http://word.mvps.org/FAQs/MacrosVBA/InterceptSavePrint.htm
    and:
    http://word.mvps.org/FAQs/MacrosVBA/AppClassEvents.htm

    Note that I haven't included the code that actually adds the watermarks - all it now outputs is a message box showing the sections to be processed. I'll leave that part to you. I also haven't tested whether you can actually reliably retrieve the required data this way - you can indeed retrieve it from the Print Dialogue, but doing that directly ordinarily doesn't return the values you're interested in until after the print job has been submitted.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Thursday, December 18, 2014 1:39 PM

All replies

  • When Word inserts a watermark, it typically applies that watermark to the whole document. Even if you were to specify a single Section when adding content to use as a watermark, the watermark is liable to apply to other Sections as well unless both the section of interest and the succeeding Section have their headers unlinked from the previous Section. For code to manage watermarking that way, see: https://social.technet.microsoft.com/Forums/sharepoint/en-US/8be8a3a3-e0ef-4950-b36f-477e245eea1b/unique-watermarks-per-section?forum=word . Even with the approach taken there, unless your user adds the watermark to whatever is the current Section, once they go into the backstage view they may not be able to say for sure what the Section # is that they want to apply the watermark to.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, December 18, 2014 3:57 AM
  • Hi Paul

    Thanks for your reply. I might not have been clear enough with my wording.

    What I need to know is which section the user is going to print. I then will apply the watermarks accordingly.

    Thanks, Martin

    Thursday, December 18, 2014 10:42 AM
  • Your wording was certainly clear enough. My point is that once a user enters the backstage for printing they may not be able to see or scroll to the page concerned to identify the Section # from the status bar. Furthermore, unless the Section header for the Section to be printed is unlinked from both the previous and succeeding Section, you cannot limit the addition of the watermark to just that Section. You also need to be aware that every Section has three independent headers and footers (wdHeaderFooterPrimary, wdHeaderFooterFirstPage, wdHeaderFooterEvenPages). Consequently, you may need to apply the watermark to any or all of these.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, December 18, 2014 11:03 AM
  • Hi Paul

    Thanks so much for your reply and the the time you take for doing this!

    The watermark is going to be a Text the user selects from a drop down in the back stage view. It is a mail merge letter (up to 400 sections).

    What I need to know is has the user selected:

    • Print all pages.
    • Print Current Page
    • Print from S1-S10 (Section 1 to Section 10)

    Since the letter header are not connected (we have dynamic data in the header lines from the mail merge), I need to apply the watermark in every section (and all different header within each section) of the document. Therefore it would be very cool if I know in the Event DocumentBeforePrint which pages, sections, ... the user wants to print.

    Thanks so much for any help

    Martin

    Thursday, December 18, 2014 12:31 PM
  • In that case, you'd probably need to use a DocumentBeforePrint macro, coded along the lines of:

    Private Sub wdApp_DocumentBeforePrint(ByVal Doc As Document, Cancel As Boolean)
    Dim StrPrn As String, StrRng As String
    'Retrieve the print parameters from the FilePrint Dialog
    With Application.Dialogs(wdDialogFilePrint)
        'If Print =
        'All, StrPrn = 0
        'Current Page, StrPrn = 2
        'Pages, StrPrn = 4
        StrPrn = .Range
        'If StrPrn = 4, then StrRng holds the range to be printed
        StrRng = .Pages
    End With
    Select Case StrPrn
      Case 0: StrRng = "1" & "-" & ActiveDocument.Sections.Count
      Case 2: StrRng = Selection.Sections.First.Index
      Case 4
        If InStr(StrRng, "p") > 0 Then
          MsgBox "Please specify only Section #s", vbExclamation
          Cancel = True
          Exit Sub
        End If
        StrRng = Replace(StrRng, "s", "")
    End Select
    StrRng = ParseNumberString(StrRng, ",", "-")
    'StrRng now holds an itemised list of Section #s for further processing
    MsgBox StrRng
    End Sub

    Function ParseNumberString(StrIn As String, strSS, strGS)
    Dim i As Long, j As Long, StrTmp As String, Arr As Variant
    Arr = Filter(Split(StrIn, strSS), strGS)
    For i = 0 To UBound(Arr)
      StrTmp = ""
      For j = Val(Arr(i)) To Split(Arr(i), strGS)(1)
        StrTmp = StrTmp & strSS & j
      Next
      StrIn = Replace(StrIn, Arr(i), Mid(StrTmp, 2))
    Next
    ParseNumberString = StrIn
    End Function

    To use code like this, see:
    http://word.mvps.org/FAQs/MacrosVBA/InterceptSavePrint.htm
    and:
    http://word.mvps.org/FAQs/MacrosVBA/AppClassEvents.htm

    Note that I haven't included the code that actually adds the watermarks - all it now outputs is a message box showing the sections to be processed. I'll leave that part to you. I also haven't tested whether you can actually reliably retrieve the required data this way - you can indeed retrieve it from the Print Dialogue, but doing that directly ordinarily doesn't return the values you're interested in until after the print job has been submitted.


    Cheers
    Paul Edstein
    [MS MVP - Word]


    Thursday, December 18, 2014 1:39 PM
  • Hi Paul

    One more question. Accessing the print parameters from Application.Dialogs(wdDialogFilePrint) object will not return the values the user set in the backstage print section. It seems that the print parameters from the backstage print section is stored somewhere else.

    Do you have any clue where I possibly could finde them?

    Martin

    Thursday, February 19, 2015 6:04 AM
  • Hi Martin

    Basically, it's not possible for you to pick up the settings from the built-in Backstage controls. If you need that, then you need to create a Custom Tab for the Backstage to replace the built-in one and hide the built-in one.


    Cindy Meister, VSTO/Word MVP, my blog

    Thursday, February 19, 2015 6:13 PM
    Moderator
  • Hi Cindy

    Super advice. Thanks so much for your help.

    Martin

    Monday, February 23, 2015 8:11 AM
  • Hi Cindy

    The draw back I have is with your solution is that one can not dynamically hook the GetVisible callback from a build-in tab (Print) to steer if I'd like to show the custom print tab or the built-in print tab in the backstage view. I read this on another reply from you in a forum and can confirm your finding.

    I hold on to a a thin straw, you wrote: "Basically, it's not possible...". Is there technically any way at all to get hold of that information from the backstage controls any other way? I master VB.NET, C#, VSTO, ... you name it. Any way to intercept this information and bring it to the DocumentBeforePrint event?

    Thanks again for your help.

    Martin

    Wednesday, February 25, 2015 4:44 PM
  • Hi Martin

    << Is there technically any way at all to get hold of that information from the backstage controls any other way?>>

    Not that I know of, with the possible exception of leveraging the Windows API, but I'm not conversant enough with that to know if you can pick up activity in a Backstage "window" and interpret it.


    Cindy Meister, VSTO/Word MVP, my blog

    Monday, March 2, 2015 10:57 AM
    Moderator
  • Hi Cindy

    Thanks so much for your replay. Would you be able to suggest a forum where I could find the right audience asking about the Windows API & Backstage tab?

    Thanks a ton.

    Martin

    Monday, March 2, 2015 10:59 AM