How do I generate a numbered paragraph Word Cross Reference field in VB?

Anonymous
2010-10-06T22:23:01+00:00

Hi There,

Does anyone know how the 9 digit unique number used in a Microsoft Word 2003 SP3 cross reference field for a numbered paragraph is derived or calculated, and what VB function I can use to extract or create it?

I use a macro (see below) that creates and inserts a cross reference field. The aim is to quickly create a cross reference from a button rather than go through the tedious "insert>reference>cross reference and select" menus.

The macro tags the reference with a letter "b" followed by an 8 digit random number (eg toggle field codes shows "{ REF b70554752 \n \h }.

The behaviour of this method of cross referencing works well most of the time, but has a couple of annoying flaws.  

Firstly, the small risk that a cross reference may be given the same number (ie the random number generator kicscks out the same number twice in a document!). Not really concerned about this as it is very unlikely to occur.

Secondly, and by far the biggest problem, is where a cross reference is created to a numbered paragraph, and the numbered paragraph is subsequently deleted. Instead of the cross reference going to "Error! - Reference Not Found" (as a 'manually inserted' cross reference does), it updates to a different, usually nearby, numbered paragraph.

On comparing the format of a 'manually inserted' cross reference field with my macro generated field, it appears that the "Microsoft" cross reference uses a 9 digit number that is somehow created uniquely based on the paragraph (for example "{ REF _Ref274201605 \n \h }"). This means that if the paragraph referred to is deleted, the reference is no longer valid and the bookmark (correctly) errors ever time.

Does anyone know how the 9 digit unique number used in a Microsoft Word 2003 SP3 cross reference field for a numbered paragraph is derived or calculated, and what VB function I can use to extract or create it?

Many thanks in advance!

Cheers

...Steve

For reference, the current macro is as follows:

___________________

Sub Add_crossRef_to_selected_para()

Dim n As Long

Dim myBookmark As String

n = Int(Rnd() * 100000000) + 1

With ActiveDocument.Bookmarks

.Add Range:=Selection.Range, Name:="b" & n

.DefaultSorting = wdSortByLocation

.ShowHidden = True

End With

Selection.InsertCrossReference ReferenceType:="Bookmark", ReferenceKind:= _

wdNumberNoContext, ReferenceItem:="b" & n, InsertAsHyperlink:=True, _

IncludePosition:=False

End Sub

________________________

Microsoft 365 and Office | Word | For home | Windows

Locked Question. This question was migrated from the Microsoft Support Community. You can vote on whether it's helpful, but you can't add comments or replies or follow the question.

0 comments No comments

41 answers

Sort by: Newest
  1. Paul Edstein 82,871 Reputation points Volunteer Moderator
    2010-10-09T22:33:08+00:00

    Hi Steve,

    For me, the cross-references appear to work regardless of the paragraph length and, if there is more than one matched paragraph (eg:

    1.1 The quick brown fox jumps over the lazy dog.

    (a) The quick brown fox jumps over the lazy dog.

    1.2 The quick brown fox jumps over the lazy dog.

    (a) The quick brown fox jumps over the lazy dog.

    with the selection point in either (a)) cross-references to both paragraphs will be inserted.

    As for the 'full cross reference', I don't believe there is a cross-referencing scheme in Word that supports this unless the paragraph itseld incorporates the previous levels ... but then there would be less of a risk of duplicates too.


    Cheers,

    macropod MS MVP - Word

    Was this answer helpful?

    0 comments No comments
  2. Anonymous
    2010-10-09T21:18:56+00:00

    Hi Macropod,

    Ooo so close again:-)

    This one doesn't create any cross reference where the para is longer than a single line (meaning the para has wrapped around to the next line). Otherwise, it seems to work on initial testing.

    And I confirm that if I have two or more paragraphs at the same level with the same text it seems to enter the cross ref to the first instance of that text. I can probably live with that, although it would be better (and easier to identify when it occurs) if the (a) or (i) style paras would create a full cross reference that includes the previous levels (eg 2.2.2(a) instead of just (a)).

    Cheers

    ...Steve

    Was this answer helpful?

    0 comments No comments
  3. Paul Edstein 82,871 Reputation points Volunteer Moderator
    2010-10-08T10:56:03+00:00

    Hi Steve,

    Try this version:

    Sub Demo()

    Dim i As Integer, xRefs As Variant, MyRange As Range

    xRefs = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)

    With Selection

      Set MyRange = Selection.Paragraphs(1).Range

      MyRange.End = MyRange.End - 1

      For i = 1 To UBound(xRefs)

        If Split(Trim(xRefs(i)), " ")(0) = .Range.ListFormat.ListString Then

          If Trim(xRefs(i)) = .Range.ListFormat.ListString & " " & MyRange.Text Then

            .InsertCrossReference ReferenceType:=wdRefTypeNumberedItem, ReferenceKind:=wdNumberNoContext, _

            ReferenceItem:=i, InsertAsHyperlink:=True, IncludePosition:=False

          End If

        End If

      Next

    End With

    Set MyRange = Nothing

    End Sub

    Note: it'll still produce spurious results if you've got two or more paragraphs at the same level with the same text.


    Cheers,

    macropod MS MVP - Word

    Was this answer helpful?

    0 comments No comments
  4. Anonymous
    2010-10-08T08:37:44+00:00

    Oooo you're good:-)

    Works for paras where the para number is unique, but where they aren't (eg I have my heading 4 as just "(a)") the macro loops and finds all the para (a)'s. (Like "(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)(a)....")

    eg, I usually have:

    1. Heading 1

        1.1 Heading 2

           1.1.1 Heading 3

                   (a) Heading 4

                             (i) Heading 5

    So when a cross ref by your macro for, say, clause 1.1.1(a) is created it makes lots of "(a)"'s instead of just a single 1.1.1(a).

    Hope that makes sense!

    Cheers

    ...Steve

    Was this answer helpful?

    0 comments No comments
  5. Paul Edstein 82,871 Reputation points Volunteer Moderator
    2010-10-08T04:30:08+00:00

    Hi Steve,

    OK, try it this way (should be very quick, too):

    Sub Demo()

    Dim i As Integer, xRefs As Variant

    xRefs = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)

    With Selection

      For i = 1 To UBound(xRefs)

        If Split(Trim(xRefs(i)), " ")(0) = .Range.ListFormat.ListString Then _

        .InsertCrossReference ReferenceType:=wdRefTypeNumberedItem, ReferenceKind:=wdNumberNoContext, _

        ReferenceItem:=i, InsertAsHyperlink:=True, IncludePosition:=False

      Next

    End With

    End Sub


    macropod MS MVP - Word

    Was this answer helpful?

    0 comments No comments