Solved

Navigating Bookmarks in Microsoft Word VBA

Posted on 2009-05-08
6
1,722 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
ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 

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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article will guide you to convert a grid from a picture into Excel format using Microsoft OneNote and no other 3rd party application.
Outlook Free & Paid Tools
The viewer will learn how to simulate a series of sales calls dependent on a single skill level and learn how to simulate a series of sales calls dependent on two skill levels. Simulating Independent Sales Calls: Enter .75 into cell C2 – “skill leve…
In a previous video Micro Tutorial here at Experts Exchange (http://www.experts-exchange.com/videos/1358/How-to-get-a-free-trial-of-Office-365-with-the-Office-2016-desktop-applications.html), I explained how to get a free, one-month trial of Office …

821 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