Solved

Navigating Bookmarks in Microsoft Word VBA

Posted on 2009-05-08
6
1,688 Views
Last Modified: 2012-05-06
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
                     and
      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.

Then call:
       "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.

Please Help!

0
Comment
Question by:richelieu7777
  • 4
  • 2
6 Comments
 
LVL 23

Accepted Solution

by:
irudyk earned 500 total points
ID: 24336109
You could try using the current cursor location's vertical and horizontal position on the page using:
    Selection.Range.Information(wdVerticalPositionRelativeToPage)
    Selection.Range.Information(wdHorizontalPositionRelativeToPage)
Then you could get the vertical and horizontal position of each bookmark by using:
    ActiveDocument.Bookmarks(i).Range.Information(wdVerticalPositionRelativeToPage)
    ActiveDocument.Bookmarks(i).Range.Information(wdHorizontalPositionRelativeToPage)
Using the above methods you could then modify your code accordingly to select the desired bookmark.  The current cursor's location and each bookmarks horizontal postion would be used for times when the cursor location may be on the same vertical postion as the next bookmark.
0
 

Author Comment

by:richelieu7777
ID: 24336608
OK.  I'll try that in just a few minutes and let you know how it goes
0
 

Author Comment

by:richelieu7777
ID: 24338109
irudyk:
I don't that will work since there may be multiple bookmarks on multiple pages.   Therefore, it's possible that multiple bookmarks could have the same "wdVerticalPositionRelativeToPage" property.  For instance, if a document had 10 pages, and if each page had a bookmark on the top of each page, then each bookmark's "wdVerticalPositionRelativeToPage" property would be the same.  Therefore,  no way to distinguish one from another.

If there were a way of determining which *page* a bookmark was on and, correspondingly, which *page* the cursor was on, then that, combined with the "wdVerticalPositionRelativeToPage" should be enough information to uniquely identify a bookmark; but I can't find a way to identify a bookmark by the page on which it lies.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:richelieu7777
ID: 24338171
Aha.

I can use "ActiveDocument.Bookmarks(1).Range.Information(wdActiveEndPageNumber)"

to get the page number of both 1)  the cursor and 2) each bookmark
0
 

Author Closing Comment

by:richelieu7777
ID: 31579410
Additionally, you must also use:

 "ActiveDocument.Bookmarks(1).Range.Information(wdActiveEndPageNumber)"

to get the page number of both 1)  the cursor and 2) each bookmark.  Then, each bookmark can be uniquely identified by both its page number  and where it is on the page.
0
 
LVL 23

Expert Comment

by:irudyk
ID: 24338274
richelieu7777:
Yep, you are correct in that you must also use ActiveDocument.Bookmarks(1).Range.Information(wdActiveEndPageNumber) to get the page number of both the cursor and each bookmark so that each bookmark can be uniquely identified by both its page number and where it is on the page...poor testing on my part there!
I'm glad you were able to work through what I suggested into a solution that fully worked! Thanks for grade :)
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
This article will show you how to use shortcut menus in the Access run-time environment.
Learn how to make your own table of contents in Microsoft Word using paragraph styles and the automatic table of contents tool. We'll be using the paragraph styles in Word’s Home toolbar to help you create a table of contents. Type out your initial …
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now