MS Word

Perform Find and Replace Operations with Complex Formatting

The Problem:

I tried the replace-with-subscript trick mentioned in (see "Replace with a Subscript"), and it's fine as far as it goes. But what I need to do is find each table caption; check to see if the paragraph before it uses a boxed style; and, if it doesn't, apply a top border to the table caption. I can't do that with Replace, now can I?

The Solution:

Not as you describe it, no. But a macro using Find can locate the table captions, check them, and apply the border as needed. The macro shown in Example 8-13 searches for each paragraph using the Table Caption style and applies a top border to that paragraph if the previous paragraph doesn't have a bottom border. You'll need to adapt the specifics, but the principle should work for you.

Macro to search for specific formatting and check nearby formatting

Example 8-13.
 Sub Check_Table_Captions()
     'go through the document for paragraphs in the Table Caption style
     'check if the paragraph before has a bottom border
     'if not, apply a top border to the Table Caption paragraph
     Dim i As Integer
     Dim strMTitle As String
     On Error GoTo ErrorHandler
     strMTitle = "Apply Upper Border to Table Caption Style"
    If MsgBox(Prompt:="Apply the upper borders to the Table Caption style?", _
       Buttons:=vbYesNo + vbQuestion, Title:=strMTitle) = vbNo Then
       Exit Sub
  End If
  For i = 2 To ActiveDocument.Paragraphs.Count
       With ActiveDocument.Paragraphs(i)
          If .Style = "Table_Caption" Then
              If .Previous.Borders(wdBorderBottom).LineStyle <> _
                 wdLineStyleSingle Then
                .Borders(wdBorderTop).LineStyle = wdLineStyleSingle
                .Borders(wdBorderTop).LineWidth = wdLineWidth100pt
                .Borders(wdBorderTop).Color = wdColorBlack
             End If
         End If
      End With
   Next i
  If Err.Number = 5834 Then
      MsgBox Prompt:="This document doesn't use the Table Caption style.", _
         Buttons:=vbOKOnly + vbInformation, Title:=strMTitle
      Exit Sub
      MsgBox Prompt:="The following error has occurred:" & vbCr & vbCr & _
          "Error Number: " & Err.Number & vbCr & vbCr & _
          "Error Description: " & Err.Description, _
          Buttons:=vbOKOnly + vbInformation, Title:=strMTitle
      Exit Sub
    End If
  End Sub

Much of this macro is straightforward if you've been following along through this tutorial, but the following points are worth noting:

  • The On Error GoTo ErrorHandler line tells VBA to trap errors and directs them to an error handler (a section of code designed to deal with errors). Unhandled errors in your macros usually display error message boxes, which are confusing for users, as many of the errors are hard to interpret. The error this macro is most likely to encounter is the active document not containing the Table Caption style. If this happens, the code after the ErrorHandler: label at the end of the macro runs, checking the error number against the number for a missing style (5834); if it matches, the error handler displays a message box explaining what has happened and then exits the macro. If there's a different error, the Else statement makes the macro display a message box giving the error's number and description. This information tends to be neither intelligible nor helpful, but it's preferable to having an error message box named Microsoft Visual Basic appear unexpectedly on the screen.

  • The For loop uses a counter (i) and runs from i = 2 to ActiveDocument.Paragraphs.Count, which is the number of paragraphs in the document. This loop enables the macro to check every paragraph in the document (skipping the first paragraph, which doesn't have a paragraph before it) for the Table Caption style.

  • The With statement works with the paragraph the loop is currently examining (ActiveDocument.Paragraphs(i)). If the paragraph's style is Table Caption, the nested If statement checks to see if the previous paragraph (.Previous) is lacking a bottom border. If it is, the three .Borders statements apply the necessary border.