Deleting Unused Bookmarks

Written by Allen Wyatt (last updated September 30, 2025)
This tip applies to Word 2007, 2010, 2013, 2016, 2019, 2021, 2024, and Word in Microsoft 365


2

Eric has a document that has many bookmarks that were either created by Word itself or are remnants of previous bookmarks no longer needed. He wonders if there is a quick way to delete all the unused bookmarks in the document.

The answer depends on what is meant by "unused." In general, there are two ways you could possibly determine if a bookmark is unused or not. If the bookmark is not the target of a cross-reference, then you might consider it unused. If the bookmark is "empty," meaning it doesn't contain text, you might also consider it unused.

Notice that in these two measures, I used the term "might." That was deliberate, because you could have empty bookmarks that have a use—you might use them to jump to locations within your document, for instance. In that case, calling an empty bookmark "unused" would be a misnomer.

The same could be said about bookmarks that aren't targets of cross-references. You might, again, have them defined to mark places to which you want to jump or text that you might way to reference in a macro or text that will be referenced by some other type of field.

When it comes to bookmarks created by Word—generally referred to as "system bookmarks"—things get even murkier. Word routinely creates bookmarks for use by many fields. The names of these system bookmarks begin with an underscore, and bookmarks whose names begin with underscores are considered "hidden" by Word. So, these system bookmarks are normally maintained in the background, out of sight. But, they are there, and they may serve a purpose, even a purpose that may be hard to discern.

Let's say, though, that you decide you do want to delete all the empty bookmarks and all the system bookmarks defined in your document. The easiest way to do this is to use a macro, such as the following:

Sub DeleteUnusedBookmarks1()
    Dim bm As Bookmark
    Dim J As Integer
    Dim C1 As Integer
    Dim C2 As Integer
    Dim sMsg As String

    C1 = ActiveDocument.Bookmarks.Count

    For J = ActiveDocument.Bookmarks.Count To 1 Step -1
        Set bm = ActiveDocument.Bookmarks(J)

        ' Delete if bookmark is empty or system-generated
        If bm.Range.Start = bm.Range.End Or Left(bm.Name, 1) = "_" Then bm.Delete
    Next J

    C2 = ActiveDocument.Bookmarks.Count

    sMsg = "There were originally " & C1 & " bookmarks, "
    sMsg = sMsg & "and " & C1-C2 & " unreferenced bookmarks "
    sMsg = sMsg & "have been deleted. "
    sMsg = sMsg & "There are " C2 & " bookmarks remaining."
    MsgBox sMsg, vbInformation
End Sub

The macro steps through all bookmarks and, if the bookmark is empty (it doesn't refer to a range of text) or its name begins with an underscore, it is deleted. When done, you'll see a message about how many bookmarks were deleted.

If you want to get just a bit more selective and delete only system bookmarks and those that are not referenced anywhere in your document, then the macro needs to be a bit longer:

Sub DeleteUnusedBookmarks2()
    Dim bm As Bookmark
    Dim C1 As Integer
    Dim C2 As Integer
    Dim bname As String
    Dim found_it As Boolean
    Dim sMsg As String
    Dim sfc As Boolean

    ' Remember whether field codes are shown or not
    sfc = ActiveWindow.View.ShowFieldCodes

    ' Show field codes, so that their code string
    ' is available to Find
    ActiveWindow.View.ShowFieldCodes = True

    C1 = ActiveDocument.Bookmarks.Count

    For Each bm In ActiveDocument.Bookmarks
        bname = bm.Name
        If Left(bname, 1) = "_" Then
            ' System-generated bookmark
            bm.Delete
        Else
            ' Start search at beginning of document
            ActiveDocument.Range(0, 0).Select

            With Selection.Find
                .Text = bname
                .Execute
                found_it = .Found
            End With
            If found_it = False Then bm.Delete
        End If
    Next bm

    C2 = ActiveDocument.Bookmarks.Count
    ActiveWindow.View.ShowFieldCodes = sfc

    sMsg = "There were originally " & C1 & " bookmarks, "
    sMsg = sMsg & "and " & C1-C2 & " unreferenced bookmarks "
    sMsg = sMsg & "have been deleted. "
    sMsg = sMsg & "There are " & C2 & " bookmarks remaining."
    MsgBox sMsg, vbInformation
End Sub

In this case the macro turns on the display of field codes so that Find and Replace can be used to locate text within the codes. This allows the macro to find whether a bookmark name is used in any of the field codes. If it is not used in any field codes, then the bookmark is deleted. The bookmark is also deleted if its name begins with an underscore. Upon completion, a recap of what was deleted is also presented.

Note:

If you would like to know how to use the macros described on this page (or on any other page on the WordTips sites), I've prepared a special page that includes helpful information. Click here to open that special page in a new browser tab.

WordTips is your source for cost-effective Microsoft Word training. (Microsoft Word is the most popular word processing software in the world.) This tip (13958) applies to Microsoft Word 2007, 2010, 2013, 2016, 2019, 2021, 2024, and Word in Microsoft 365.

Author Bio

Allen Wyatt

With more than 50 non-fiction books and numerous magazine articles to his credit, Allen Wyatt is an internationally recognized author. He is president of Sharon Parq Associates, a computer and publishing services company. ...

MORE FROM ALLEN

Correctly Saving Delimited Files

Delimited files are often created through Excel so that your data can be exported to other programs. If the delimited ...

Discover More

Easily Entering Dispersed Data

Need to enter information into a bunch of cells that aren't anywhere near each other in the worksheet? Here's a handy way ...

Discover More

Quickly Increasing Point Size

Want to adjust the size of a text selection? Here's a quick shortcut to increase the size.

Discover More

The First and Last Word on Word! Bestselling For Dummies author Dan Gookin puts his usual fun and friendly candor back to work to show you how to navigate Word 2019. Spend more time working and less time trying to figure it all out! Check out Word 2019 For Dummies today!

More WordTips (ribbon)

Removing All Bookmarks

Need to get rid of a lot of bookmarks all at once? Word doesn't provide a way to do it, but you can use the short macro ...

Discover More

Fields in Footnotes Won't Update Automatically

Fields can be very helpful for including dynamic information in your documents, such as cross-references. It can be ...

Discover More

Bookmark Error when Printing

Bookmarks are commonly used in Word documents as a way to cross-reference information. If the bookmark referenced by the ...

Discover More
Subscribe

FREE SERVICE: Get tips like this every week in WordTips, a free productivity newsletter. Enter your address and click "Subscribe."

View most recent newsletter.

Comments

If you would like to add an image to your comment (not an avatar, but an image to help in making the point of your comment), include the characters [{fig}] (all 7 characters, in the sequence shown) in your comment text. You’ll be prompted to upload your image when you submit the comment. Maximum image size is 6Mpixels. Images larger than 600px wide or 1000px tall will be reduced. Up to three images may be included in a comment. All images are subject to review. Commenting privileges may be curtailed if inappropriate images are posted.

What is nine minus 4?

2025-09-29 10:36:07

Andrew

Additional possibilities/probabilities are that a bookmark may be referenced in a story outside of the main story and that an empty bookmark may be used to reference a position in the document (not just the text bookmarked). For example, I very commonly find the need to use an empty bookmark to mark the last page of a multi-section portion of a document so that page numbers in a footer may be of the "Page X of Y" type (in which case the {SectionPages} field doesn't work).

Second, I try not to use Find in macros unless necessary. Greg Maxey's article at https://gregmaxey.com/word_tip_pages/words_fickle_vba_find_property.html is absolutely definitive and *must* be studied in order to use .Find in VBA for anything other than simple searches of "easy" text. So for my version of a macro on solving the bookmark problem I use string search of the bookmark name in the field text. My implementation is sort of naive in that it is case sensitive--so far not a problem in that I almost always create references using the cross-reference command in the ribbon--and I do not check that the fields are only of an appropriate type (Ref, PageRef, etc.), but this seems not to have been a problem in my work.

Sub Delete_Unreferenced_Bookmarks()
' Delete unreferenced bookmarks in ActiveDocument.
Const ProcedureID = "Delete_Unreferenced_Bookmarks()"
Dim b As Bookmark
Dim r As Range
Dim F As Field
Dim InUse As Boolean
Dim Stories As Collection

Set Stories = AllStories() ' Obtain a collection of all of ActriveDocument's stories.
ActiveDocument.Bookmarks.ShowHidden = True
Application.UndoRecord.StartCustomRecord ProcedureID
For Each b In ActiveDocument.Bookmarks
InUse = False
For Each r In Stories
If Not InUse Then
For Each F In r.Fields
If Not InUse Then If InStr(1, r.Text, b.Name) Then InUse = True
Next F
End If
Next r
If Not InUse Then b.Delete
Next b
Application.UndoRecord.EndCustomRecord
End Sub

Function All_Stories() As Collection
' Return a Collection of all Stories in ActiveDocument to permit the caller to
' conveniently deal with the ActiveDocument's stories (abstracting the
' baggage of the ActiveDocument.StoryRanges.NextStoryRange business).
Const ProcedureID = "All_Stories()"
' Fix the skipped blank Header/Footer problem as provided by Peter Hewett (bridging any empty unlinked headers and footers).
Dim Junk As Long: Junk = ActiveDocument.Sections(1).Headers(1).Range.StoryType

Set All_Stories = New Collection

Dim Story As Range
For Each Story In ActiveDocument.StoryRanges
Do
All_Stories.Add Story.Duplicate

Dim Shape As Shape
For Each Shape In Story.ShapeRange
If Shape.TextFrame.HasText Then All_Stories.Add Shape.TextFrame.TextRange.Duplicate
Next Shape

Set Story = Story.NextStoryRange
Loop Until IsNothing(Story)
Next Story

End Function


2025-09-27 06:09:16

Barry

Whoa! Thanks again Allen. Some useful tips, but... This one seems a bit of a darastic idea. Along with the mentioned caveats there is the possibility that an 'idle' looking bookmark may be referenced from another document. Using these macros would presumeably ignore that fact and delete the bookmark?


This Site

Got a version of Word that uses the ribbon interface (Word 2007 or later)? This site is for you! If you use an earlier version of Word, visit our WordTips site focusing on the menu interface.

Videos
Subscribe

FREE SERVICE: Get tips like this every week in WordTips, a free productivity newsletter. Enter your address and click "Subscribe."

(Your e-mail address is not shared with anyone, ever.)

View the most recent newsletter.