Search code examples
.netvb.netms-wordoffice-interopoffice-addins

How do I programmatically jump from a cross reference target bookmark to the related cross reference source field in a Word document?


I have a VSTO add-in for Word. I am trying to write code that the user will execute when the cursor is in a paragraph containing a cross reference target bookmark, and which will jump the cursor to the paragraph containing the related cross reference source field.

I have made such cross reference target bookmarks visible in all my documents. (To do this, I changed _Ref to XRef in the underlying XML.) So, when I scroll through one of my documents, I can see visible bookmarks that indicate that the paragraph is the target of a cross-reference. I would execute such above described code in a paragraph that contains such a bookmark.

I know that to use code to jump in the other direction (i.e., from the source to the target), you need the bookmark name, say "XRef130657095" , and then you could do, e.g. ActiveDocument.Bookmarks("XRef130657095").Select . However, I cannot work out if it is possible to jump in the other direction.

If it is not possible via bookmarks, maybe the following will help with an alternative approach: I use numbered paragraphs throughout all of my documents. If I could identify the long paragraph number (e.g., 17.A.3.d) that is at the target bookmark location, that could help me solve this, because the cross-reference contains that number, so I could search for that number and jump to it?

Many thanks!


Solution

  • You could use something like the following. Bear in mind that there can be multiple bookmarks in a paragraph, and that there can be multiple references to any given bookmark. Maybe you know exactly what you want to do, but here, I've just selected the first reference I can find to any of the bookmarks in the paragraph that start with "_ref" and displayed a message if there were no such bookmarks or there are other references to any of them. I have only iterated the fields in the main storyrange, not other ranges such as textboxes and so on.

    Option Explicit
    Sub gotoreverseref1()
    Dim bm As Word.Bookmark
    Dim f As Word.Field
    Dim i As Long
    Dim bookmarkCount As Long
    Dim bookmarkName As String
    Dim refFound As Boolean
    Dim refFoundCount As Long
    Dim sh As Boolean
    
    refFound = False
    refFoundCount = 0
    With Selection.Paragraphs(1).Range
      ' save the .SHowhidden state and
      ' ensure we can find the bookmarks
      sh = .Bookmarks.ShowHidden
      .Bookmarks.ShowHidden = True
      bookmarkCount = .Bookmarks.Count
      For Each bm In .Bookmarks
        ' You don't have to constrain the search in this way
        If UCase(Left(bm.Name, 4)) = "_REF" Then
          bookmarkName = bm.Name
          For Each f In ActiveDocument.Fields
            If f.Type = wdFieldRef Then
              If InStr(UCase(f.Code.Text), UCase(bookmarkName)) > 0 Then
                If Not refFound Then
                  f.Select
                  refFound = True
                End If
                refFoundCount = refFoundCount + 1
              End If
            End If
          Next
        End If
      Next
      .Bookmarks.ShowHidden = sh
    End With
    If bookmarkCount = 0 Then
      MsgBox "The selected paragraph did not contain any _ref bookmarks."
    Else
      If refFound Then
        If refFoundCount > 1 Then
          MsgBox "A reference found and selected. There are " & CStr(refFoundCount) & " references to _ref bookmarks in the selected paragraph."
        End If ' no message if only one ref found
      Else
        If bookmarkCount = 1 Then
          MsgBox "There is 1 _ref bookmark in the selected paragraph but no references to it were found."
        Else
          MsgBox "There are " & CStr(bookmarkCount) & " _ref bookmarks in the selected paragraph but no references to them were found."
        End If
      End If
    End If
    End Sub