Resting Anchor

The Anchorage

Personal website of Gregory K. Maxey, Commander USN (Retired)

Content Controls – Don't Print Placeholder Text
(A Microsoft Word Help & Tip page by Gregory K. Maxey)

DISCLAIMER/TERMS OF USE

The information, illustrations and code contained in my "Microsoft Word Tips" are provided free and without risk or obligation.

Click to acces PayPal Verification Service Click to acces PayPal Verification Service

However, the work is mine. If you use it for commercial purposes or benefit from my efforts through income earned or time saved then a donation, however small, will help to ensure the continued availability of this resource.

If you would like to donate, please use the appropriate donate button to access PayPal. Thank you!


This Microsoft Word Tips & Microsoft Word Help page provides a couple of solutions to the frequently asked question, "How do I prevent the placeholder text in uncompleted content controls from printing?"  The solutions provided are a result of collaborative effort with MVP Jay Freedman.

The problem can occur often.  You prepare a form and send it out for completion.  Users complete part of the form and leave some of the content controls uncompleted.   When the form is returned and printed the placeholder text in the uncompleted content controls are printed.  This results in an unsightly finished form.

don't print cc placeholder text
Representation of a printed document with bubble added for emphasis

Unfortunately there isn't a simple solution.  There is no option in Word to exclude printing placeholder text, and without an intensive form validation process, you can't make the user fill out each field.

Each of the automated solutions provided require VBA which means the template and form documents must be macro enabled (i.e., .dotm and .docm extensions).

Method I - Detect Events/Intercept Commands/Modify Style

The first method employs the application event "DocumentBeforePrint," repurposed Print commands and a temporary modification of the placeholder text style.

Placeholder text, like most text in Word, is defined by a style.  If you temporarily set the placeholder text style font property .Hidden to true, set the application options .PrintHiddenText property to false and print the document the placeholder text will not be printed. This can of course be done manually if you have a willing group of form users, but an automated process requires a VBA solution.

Site Note Icon Notes:
     1. The Normal project is project associated with the Normal template.  It is global and always loaded.

     2.  The method is developed for Word 2010, but includes all necessary code for Word 2007 users.  Some elements (e.g., the class module) is not required for Word 2007.

VBA Script:
Option Explicit
Private WithEvents oWordApp As Word.Application
Private Sub Class_Initialize()
 Set oWordApp = Word.Application
lbl_Exit:
  Exit Sub
End Sub

Private Sub oWordApp_DocumentBeforePrint(ByVal oDoc As Document, Cancel As Boolean)
Dim bOption As Boolean
  If Not bQuickPrint Then
    'Store current user option setting
    bOption = Options.PrintHiddenText
    'Turn off printing hidden text
    Options.PrintHiddenText = False
    'Modify the placeholder text style
    ActiveDocument.Styles("Placeholder Text").Font.Hidden = True
    'Execute the print command
    CommandBars.ExecuteMso "PrintPreviewAndPrint"
    'Pause to allow printer to spool document. Then undo style modification
    Application.OnTime Now + TimeValue("00:00:05"), "RestorePlaceholders"
    'Restore user option
    Options.PrintHiddenText = bOption
  End If
lbl_Exit:
  Exit Sub
End Sub
VBA Script:
Option Explicit
Private session_clsPrint As clsPrint
Public bQuickPrint As Boolean
Private bOption as Boolean

Sub AutoExec()
 'Initialize variable and class (Word 2010 only) when Word starts
 bQuickPrint = False
 If Application.Version > 12.0 Then
   Set session_clsPrint = New clsPrint
 End If
lbl_Exit:
  Exit Sub
End Sub

Sub RestorePlaceholders()
   'Delayed call from class
   ActiveDocument.Styles("Placeholder Text").Font.Hidden = False
lbl_Exit:
  Exit Sub
End Sub

Sub FilePrint()
  'Intercepts the Word 2007 Menu>Print>Print command
  bOption = Options.PrintHiddenText
  Options.PrintHiddenText = False
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = True
  Dialogs(wdDialogFilePrint).Show
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = False
  Options.PrintHiddenText = bOption
End Sub

Sub FilePrintDefault()
  'Intercepts the Word 2007/2010 Quick Print commands
  bOption = Options.PrintHiddenText
  'Prevent double printing
  bQuickPrint = True
  Options.PrintHiddenText = False
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = True
  ActiveDocument.PrintOut Background:=False
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = False
  bQuickPrint = False
  Options.PrintHiddenText = bOption
lbl_Exit:
  Exit Sub
End Sub

Sub PrintPreviewEditMode()
  'Intercepts the Word 2010 Print Preview Edit Mode
  'There is no apparent method to intercept and modify the print preview displayed in the Word 2010 backstage view
  bOption = Options.PrintHiddenText
  Options.PrintHiddenText = False
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = True
  ActiveDocument.PrintPreview
  Options.PrintHiddenText = bOption
lbl_Exit:
  Exit Sub
End Sub

Sub FilePrintPreview()
  'Intercepts the Word 2007 Print Preview command
  bOption = Options.PrintHiddenText
  Options.PrintHiddenText = False
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = True
  ActiveDocument.PrintPreview
  Options.PrintHiddenText = bOption
lbl_Exit:
  Exit Sub
End Sub

Sub ClosePreview()
  ActiveDocument.Styles("Placeholder Text").Font.Hidden = False
  ActiveDocument.ClosePrintPreview
lbl_Exit:
  Exit Sub
End Sub

The following is an explanation of how the process more or less works:

Site Note IconNote: If you often print large forms, you may want to increase the time. This delay is needed because changing the Hidden attribute immediately (in the end of the DocumentBeforePrint routine) would happen before the PrintPreviewAndPrint command runs (We are not sure why, but it just doesn't work). 

Site Note IconNote:  Jay and I have not found a method to intercept and alter the Print Preview in the Word 2010 backstage view.  Placeholder text in will continue to display in this view even though it will not actually be printed.

Method II - Detect Events/Intercept Commands/Modify Text

The second method, similar to the first, employs the application event "DocumentBeforePrint," repurposed Print commands and a temporary alteration of the placeholder text itself.

Placeholder text, is a bit peculiar.  While it appears to be text, a content control's .PlaceholderText property is actually a Building Block object with a value.  For a more in depth discussion see:  5 Curiosities about Placeholders in Word Content Controls (for developers).  If we temporarily set the .PlaceholderText property to a single space " " before printing and restore the original text after printing the results will be similar to method I.  The code is a bit more complicated and the only advantage is we don't tinker with user options or restrict printing of hidden text in general.  The jury is still deliberating if there is any real advantage over either method, but for completeness, here it is:

Site Note Icon Note:  If you have already created the modules using Method 1 then simply delete the existing content in the modules.  Do not attempt to use both methods simultaneously.

VBA Script:
Option Explicit
Private WithEvents oWordApp As Word.Application
Private Sub Class_Initialize()
  Set oWordApp = Word.Application
End Sub
Private Sub oWordApp_DocumentBeforePrint(ByVal oDoc As Document, Cancel As Boolean)
Dim bOption As Boolean
If Not bQuickPrint Then
  'Call procedures in the standard module to alter placeholder text
  modPrint.DimensionArray
  modPrint.Processor 2
  'Execute the print command
  CommandBars.ExecuteMso "PrintPreviewAndPrint"
  'Pause to allow printer to spool document. Then call procedure to restore placeholder
  Application.OnTime Now + TimeValue("00:00:05"), "modPrint.RestorePHT"
End If
End Sub
VBA Script:
Option Explicit
Private session_clsPrint As clsPrint
Private oRngStory As Word.Range
Private lngValidator As Long
Private oCC As ContentControl
Private oShp As Shape
Private arrPHT() As String
Private i As Long
Public Type CCCollection
  Count As Long
  bContainsCCs As Boolean
End Type
Dim bContainsCCs As Boolean
Public bQuickPrint As Boolean

Sub AutoExec()
 'Initialize variable and class when Word starts
 bQuickPrint = False
 If Application.Version > 12# Then
   Set session_clsPrint = New clsPrint
 End If
lbl_Exit:
  Exit Sub
End Sub

Sub DimensionArray()
  'Count CCs in document
  i = Processor(1).Count
  ReDim arrPHT(i)
lbl_Exit:
  Exit Sub
End Sub

Sub RestorePHT()
  'Called from clsPrint
  modPrint.Processor 3
lbl_Exit:
  Exit Sub
End Sub

Sub FilePrint()
  'Intercepts the Word 2007 Menu>Print>Print command
  'Call procedures alter placeholder text
  DimensionArray
  Processor 2
  Dialogs(wdDialogFilePrint).Show
  'Call procedures to restore placeholder text
  Processor 3
lbl_Exit:
  Exit Sub
End Sub

Sub FilePrintDefault()
  'Intercepts the Word 2007/2010 Quick Print commands
  'Call procedures alter placeholder text
  DimensionArray
  Processor 2
  'Print the document
  ActiveDocument.PrintOut
  'Call procedures to restore placeholder text
  Processor 3
lbl_Exit:
  Exit Sub
End Sub

Sub PrintPreviewEditMode()
  'Intercepts the Wor 2010 PrintPreviewEditMode command
  bContainsCCs = False
  DimensionArray
  If Processor(2).bContainsCCs = True Then
    bContainsCCs = True
  End If
  ActiveDocument.PrintPreview
  If bContainsCCs Then Application.StatusBar = "CC PHT modified"
lbl_Exit:
  Exit Sub
End Sub

Sub FilePrintPreview()
  'Intercepts the Word 2007 PrintPreview command
  bContainsCCs = False
  DimensionArray
  If Processor(2).bContainsCCs = True Then
    bContainsCCs = True
  End If
  ActiveDocument.PrintPreview
  If bContainsCCs Then Application.StatusBar = "CC PHT modified"
lbl_Exit:
  Exit Sub
End Sub

Sub ClosePreview()
  Processor 3
  ActiveDocument.ClosePrintPreview
lbl_Exit:
  Exit Sub
End Sub

Function Processor(ByRef lngAction As Long) As CCCollection
  Dim oCount As Long
  i = 0
  lngValidator = ActiveDocument.Sections(1).Headers(1).Range.StoryType
  For Each oRngStory In ActiveDocument.StoryRanges
    'Iterate through all linked stories
    Select Case oRngStory.StoryType
      Case 1 To 11
        Do
          For Each oCC In oRngStory.ContentControls
            Select Case lngAction
              Case 1
                oCount = oCount + 1
              Case 2
                oCount = oCount + 1
                'Store placeholder text
                arrPHT(i) = oCC.PlaceholderText
                'Set temporary placeholder text
                oCC.SetPlaceholderText , , " "
                i = i + 1
              Case 3
               If oCC.ShowingPlaceholderText Then
                 'Restore stored placeholder text
                 oCC.SetPlaceholderText , , arrPHT(i)
               End If
               i = i + 1
            End Select
          Next oCC
          Select Case oRngStory.StoryType
            Case 6, 7, 8, 9, 10, 11
              If oRngStory.ShapeRange.Count > 0 Then
                For Each oShp In oRngStory.ShapeRange
                  On Error GoTo Err_HasText
                  If oShp.TextFrame.HasText Then
                    For Each oCC In oShp.TextFrame.TextRange.ContentControls
                      Select Case lngAction
                        Case 1
                          oCount = oCount + 1
                        Case 2
                          'Store placeholder text
                          arrPHT(i) = oCC.PlaceholderText
                          'Set temporary placeholder text
                          oCC.SetPlaceholderText , , " "
                          i = i + 1
                        Case 3
                          If oCC.ShowingPlaceholderText Then
                           'Restore stored placeholder text
                           oCC.SetPlaceholderText , , arrPHT(i)
                          End If
                         i = i + 1
                      End Select
                    Next oCC
                  End If
                  On Error GoTo 0
Err_HasText_ReEntry:
                Next oShp
              End If
            Case Else
            'Do Nothing
          End Select
          'Get next linked story (if any)
          Set oRngStory = oRngStory.NextStoryRange
        Loop Until oRngStory Is Nothing
      Case Else
    End Select
  Next oRngStory
  Processor.Count = oCount
  If oCount > 0 Then
    Processor.bContainsCCs = True
  End If
  Exit Function
Err_HasText:
  Resume Err_HasText_ReEntry
End Function

The process and procedures are similar to Method I, instead of changing the placeholder text style, it:

Method III - Document Content Control Events/Custom Placeholder Text

Method III employs an individual document template, the Document_ContentControlOnEnter & Document_ContentControlOnExit events and custom placeholder text applied dynamically as the user completes the form.

cc do not print pht 2
Design Mode view

cc do not print pht 3
cc do not print pht
VBE code pane
VBA Script:
Option Explicit
Private Sub Document_New()
  ActiveDocument.SelectContentControlsByTitle("Name").Item(1).Range.Select
lbl_Exit:
  Exit Sub
End Sub

Private Sub Document_Open()
  ActiveDocument.SelectContentControlsByTitle("Name").Item(1).Range.Select
lbl_Exit:
  Exit Sub
End Sub

Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
Select Case ContentControl.Title
  Case "Name"
    ContentControl.SetPlaceholderText , , "Click and enter your name here."
  Case "Address"
    ContentControl.SetPlaceholderText , , "Click and enter your address here."
  Case "Phone Number"
    ContentControl.SetPlaceholderText , , "Click and enter your phone number here."
End Select
lbl_Exit:
  Exit Sub
End Sub

Private Sub Document_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
  If ContentControl.ShowingPlaceholderText = True Then
    ContentControl.SetPlaceholderText , , " "
  End If
lbl_Exit:
  Exit Sub
End Sub

Unlike the previous methods, this method has no relationship with the application print processes.  It simply uses the built-in document events to dynamically apply or remove a visible placeholder text as the user navigates the form. 

Site Note IconNote:  This method is the least robust since it is possible that a user enters a CC displaying the visible placeholder text and then prints the document without first exiting the CC.  You, or your users, must be sure to physically "exit" any uncompleted document CC.

Conclusion

If properly applied each of the three methods will result in a more appealing printed form.

cc do not print pht 5

That's it! I hope you have found this tips page useful and informative.

Share Stumbleupon

PAYMENTS/DONATIONS

Click to acces PayPal Verification Service Click to acces PayPal Verification Service

Do you want to make a payment for consulting work or donate to help support this site?

PayPal is a safe, easy way to pay online.

Use the appropriate currency "Donate" button to make a payment or donation.


Search my site or the web using Google Search Engine

Google Search Logo

Or

JustAnswerAsk a Word Expert OnlineSubmit