Solved

Navigating Bookmarks in Microsoft Word VBA

Posted on 2009-05-08
6
1,794 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 

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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

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

My attempt to use PowerShell and other great resources found online to simplify the deployment of Office 365 ProPlus client components to any workstation that needs it, regardless of existing Office components that may be needing attention.
Ever visit a website where you spotted a really cool looking Font, yet couldn't figure out which font family it belonged to, or how to get a copy of it for your own use? This article explains the process of doing exactly that, as well as showing how…
Learn how to create and modify your own paragraph styles in Microsoft Word. This can be helpful when wanting to make consistently referenced styles throughout a document or template.
This Micro Tutorial well show you how to find and replace special characters in Microsoft Word. This is similar to carriage returns to convert columns of values from Microsoft Excel into comma separated lists.
Suggested Courses
Course of the Month8 days, 21 hours left to enroll

617 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