Navigating Bookmarks in Microsoft Word VBA
Posted on 2009-05-08
Does anyone know of a robust method (macro) of navigating to the immediately next bookmark right after the current cursor position in a Document.
I am having a heck of a time.
For instance, let's say a large document has many bookmarks, and, let's say one bookmark is at character position #5000, the next bookmark is at character position #10000, and the cursor is at character position #7500. When this macro is called, it should move the cursor from character position #7500 to position #10000. (I don't know how to locate a Bookmark by the *line* number on which it is located.)
I *do* know that the Bookmark collection has "Start" and "End" properties. These do *not* refer to *line* numbers, but, rather, to *character* positions.
So, in my first attempt at this, I thought it would be a simple matter of:
1) Getting the absolute character position of the cursor via:
Dim iCharNum As Long
iCharNum = ActiveDocument.Range(1, Selection.Start).Characters.Count
2) Indexing through all the "ActiveDocument.Bookmarks(i).Start" properties until I found the one that is:
a) closest to the cursor
b) either on or after the cursor
3) Then, once I located the bookmark and its name call:
Selection.GoTo What:=wdGoToBookmark, Name:=sName
This method works *great* . . . unless the document has *hyperlinks". If it does, then the "Start" property of the bookmark is skewed. (A hyperlink has a "Range.Start" and "Range.End" property. Again, these are *character* positions, not line numbers.)
Back to the example: let's look at the bookmark at character position #10000, therefore, its "Bookmark.Start" property is "10000". Let's call this bookmark "B10000".
Let's put the cursor right at this bookmark.
"iCharNum = ActiveDocument.Range(1, Selection.Start).Characters.Count"
to verify that BM10000 is, in fact, at 10000.
At this point, iCharNum and BM10000.Start are equal.
Now let's paste a hyperlink over characters between the bookmark at character position #5000 and B10000. But when we add it, let's be careful to paste over existing characters so that when the cursor is located right at BM10000, iCharNum is *still* 10000.
You will notice, however, that the "Start" property of B10000 is *not* 10000 anymore even though the value of iCharNum *is* 10000. That is, even though the physical position of B10000 did *not* change in the document, its "Start" property *did* change--it is skewed. (I have found that the amount that it is skewed is a function of the number of hyperlinks and the values of each hyperlinks "Range.Start" and "Range.End" values; but I have found no consistency to this skewing and cannot develop a work-around).
Because of this, I can no longer depend on any bookmark's "Start" property anymore to determine where it is in the document. Therefore, I cannot find the next bookmark to navigate to.