When I write documents in Word, I like to mark them up with notes that are flagged with customized character styles and usually enclosed in brackets. The VBA macros on this page were designed to help manipulate such notes. They make it easy, for example, to create one, select one, jump to the next one, and convert one into regular text. When a clean version of the document is needed, another macro can delete them all instantly.
True, Word has its own annotation features like comments and hidden text. But I like this way better.
In my experience, using the keyboard instead of the mouse (as much as possible) is essential for avoiding forearm and wrist pain. It is also faster. Most of these macros are really only useful if assigned to keystrokes. General information on Word macros here.
Some of the macros assume that you have character styles named, e.g., “Flag 1”. This document contains sample styles by way of illustration. Note that styles, too, can be assigned directly to keystrokes, but in some cases I use macros instead (see “Set style to ‘Flag 1’”).
My general macros for Word are here.
(not including the brackets themselves)
Suggested keystroke: Ctrl-[
Sub SelectToBracketsExclusive()
With Selection.Find
.ClearFormatting
.Text = "["
.Forward = False
.MatchWildcards = False
.Wrap = wdFindStop
.Execute
End With
Selection.Extend
With Selection.Find
.Text = "]"
.Forward = True
.Execute
.Text = ""
End With
Selection.MoveStart Unit:=wdCharacter, Count:=1
Selection.MoveEnd Unit:=wdCharacter, Count:=-1
End Sub
(including the brackets themselves)
Suggested keystroke: Ctrl-Shift-[
Sub SelectToBracketsInclusive()
With Selection.Find
.ClearFormatting
.Text = "["
.Forward = False
.MatchWildcards = False
.Wrap = wdFindStop
.Execute
End With
Selection.Extend
With Selection.Find
.Text = "]"
.Forward = True
.Execute
.Text = ""
End With
End Sub
Suggested keystroke: Ctrl-]
Sub AddBracketsAroundSelection()
' Simply inserts adjacent brackets if nothing is selected
If Selection.Type = wdSelectionIP Then
Selection.InsertBefore "["
Selection.InsertAfter "]"
Selection.MoveStart Unit:=wdCharacter, Count:=1
Selection.Collapse Direction:=wdCollapseStart
Else
' Shrinks selection to exclude leading or trailing spaces
' Also excludes trailing paragraph break
While Selection.Characters.First = " "
Selection.MoveStart Unit:=wdCharacter, Count:=1
Wend
While Selection.Characters.Last = " " Or Selection.Characters.Last = vbCr
Selection.MoveEnd Unit:=wdCharacter, Count:=-1
Wend
Selection.InsertBefore "["
Selection.InsertAfter "]"
' Brackets shed any character style acquired from selection
Selection.Characters.First.Font.Reset
Selection.Characters.Last.Font.Reset
End If
End Sub
(and delete the brackets themselves)
Suggested keystroke: Ctrl-Shift-]
Sub ClearTextWithinBrackets()
' Removes char style / formatting within brackets, deletes the brackets
Application.ScreenUpdating = False
ActiveDocument.Bookmarks.Add Name:="LastPosition"
' First step: select text within brackets
With Selection.Find
.ClearFormatting
.Text = "["
.Forward = False
.MatchWildcards = False
.Wrap = wdFindStop
.Execute
End With
Selection.Extend
With Selection.Find
.Text = "]"
.Forward = True
.Execute
.Text = ""
End With
' Second step: clear formatting in selected text and collapse selection
With Selection
.ClearFormatting
.Collapse Direction:=wdCollapseStart
End With
' Third step: delete the initial bracket
With Selection
.MoveEnd Unit:=wdCharacter, Count:=1
.Text = ""
End With
' Fourth step: find and delete the final bracket
With Selection.Find
.Text = "]"
.Forward = True
.Replacement.Text = ""
.Execute Replace:=wdReplaceOne
.Text = ""
End With
Selection.GoTo What:=wdGoToBookmark, Name:="LastPosition"
ActiveDocument.Bookmarks(Index:="LastPosition").Delete
Application.ScreenUpdating = True
End Sub
(put insertion point inside the note first)
Suggested keystroke: Alt-Ctrl-Shift-]
Sub SelectToBracketsDelete()
With Selection.Find
.ClearFormatting
.Text = "["
.Forward = False
.Wrap = wdFindStop
.Execute
End With
Selection.Extend
With Selection.Find
.Text = "]"
.Forward = True
.Execute
.Text = ""
End With
' By not using "delete" method we get around Word's habit of adding spaces
Selection.Text = ""
End Sub
Suggested keystroke: Ctrl-\
Sub SelectToStyleBoundaries()
Dim StyleName As Variant
Application.ScreenUpdating = False
Set StyleName = Selection.Style
While Selection.Characters.First.Previous.Style = StyleName
Selection.MoveStart Unit:=wdCharacter, Count:=-1
Wend
While Selection.Characters.Last.Next.Style = StyleName
Selection.MoveEnd Unit:=wdCharacter, Count:=1
Wend
Application.ScreenUpdating = True
End Sub
Suggested keystroke: Ctrl-Shift-\
Sub SelectToStyleBoundariesAndDelete()
Dim StyleName As Variant
Application.ScreenUpdating = False
Set StyleName = Selection.Style
While Selection.Characters.First.Previous.Style = StyleName
Selection.MoveStart Unit:=wdCharacter, Count:=-1
Wend
While Selection.Characters.Last.Next.Style = StyleName
Selection.MoveEnd Unit:=wdCharacter, Count:=1
Wend
Application.ScreenUpdating = True
Selection.Delete
End Sub
Suggested keystroke: Alt-Shift-F
Sub SetStyleToFlag1()
' If no text selected, select text within the nearest brackets
If Selection.Start = Selection.End Then SelectToBracketsExclusive
Selection.Style = ActiveDocument.Styles("Flag 1")
End Sub
Suggested keystroke: Ctrl-Shift-F
Sub FindNextInstanceOfFlag1()
Application.ScreenUpdating = False
' First, moves to end of Flag1 range if insertion point is in Flag1
While Selection.Characters.Last.Next.Style = "Flag 1"
Selection.MoveEnd Unit:=wdCharacter, Count:=1
Wend
Selection.Collapse Direction:=wdCollapseEnd
With Selection.Find
.ClearFormatting
.Forward = True
.Text = ""
.MatchWildcards = False
.Style = ActiveDocument.Styles("Flag 1")
.Execute
.ClearFormatting
End With
Selection.Collapse Direction:=wdCollapseStart
Application.ScreenUpdating = True
End Sub
(This affects the entire document; I do not assign it to a keystroke.)
Sub DeleteTextWithFlag1Style()
' First, confirm that user wants to do this
Dim varResponse As Variant
varResponse = MsgBox("Delete all text styled Flag 1?", vbYesNo, "Selection")
If varResponse <> vbYes Then Exit Sub
Dim oRng As Range
Set oRng = ActiveDocument.Range(Start:=0, End:=0)
With oRng.Find
' Preparation
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.MatchWildcards = False
.Wrap = wdFindContinue
' Remove Flag 1 text
.Style = ActiveDocument.Styles("Flag 1")
.Execute Replace:=wdReplaceAll
' Clean out empty bracket pairs that once held flagged text
.ClearFormatting
.Text = "[]"
.Execute Replace:=wdReplaceAll
' Clean up
.Text = ""
.Wrap = wdFindAsk
End With
End Sub
(This affects the entire document; I do not assign it to a keystroke.)
Sub DeleteAllFlaggedText()
' First, confirm that user wants to do this
Dim varResponse As Variant
varResponse = MsgBox("Delete all flagged text?", vbYesNo, "Selection")
If varResponse <> vbYes Then Exit Sub
Dim oRng As Range
Set oRng = ActiveDocument.Range(Start:=0, End:=0)
With oRng.Find
' Preparation
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.MatchWildcards = False
.Wrap = wdFindContinue
' Remove Flag 1 text
.Style = ActiveDocument.Styles("Flag 1")
.Execute Replace:=wdReplaceAll
' Remove Flag 2 text
.Style = ActiveDocument.Styles("Flag 2")
.Execute Replace:=wdReplaceAll
' Remove Flag 3 text
.Style = ActiveDocument.Styles("Flag 3")
.Execute Replace:=wdReplaceAll
' Clean out empty bracket pairs that once held flagged text
.ClearFormatting
.Text = "[]"
.Execute Replace:=wdReplaceAll
' Clean up
.Text = ""
.Wrap = wdFindAsk
End With
End Sub
Comments welcome. Updated November 17, 2021.