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: Oldest
  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-10T01:47:43+00:00

    Hi Macropod,

    Worked out that changing the ReferenceKind:=wdNumberFullContext puts in the full path so that fixes that problem.

    Definitely in mine, if a line wraps then the Xref macro doesn't insert anything.

    In your example, try modifying 1.2 to be

    1.2 The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dog.

    Then try inserting an Xref using the macro. On mine it works right up to the point I add a character to make it line wrap, and then it doesn't work

    Cheers

    ...Steve

    Was this answer helpful?

    0 comments No comments
  3. Paul Edstein 82,871 Reputation points Volunteer Moderator
    2010-10-10T02:46:22+00:00

    Hi Steve,

    It turns out the GetCrossReferenceItems collection only stores a limited # of characters (~95) for each cross-reference. Since I need to trim the Xref strings for comparison purposes anyway (which further reduces the character count), comparing, say, the first 75 characters should be sufficient.

    Thus, changing:

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

    to

    If Left(Trim(xRefs(i)), 75) = Left(MyRange.ListFormat.ListString & " " & MyRange.Text, 75) Then

    should produce acceptable results.


    Cheers,

    macropod MS MVP - Word

    Was this answer helpful?

    0 comments No comments
  4. Anonymous
    2010-10-10T04:51:25+00:00

    Hi macropod

    I've uploaded my test document (which includes the macro) here:

    http://www.sfrg.mysamford.com.au/Cross%20Reference%20test%20Document%20clean.zip

    Macro does nothing in clause 1 (the first heading 1), nor 2.1 (just disclovered that any para containing a soft return gives a nothing result anywhere in the para before or after the soft return)

    Running the macro at the end of para 2.1.3(a) gives multiple entries.

    I hope you're having fun with this challenge - it's frustrating the sx1t out of me!!

    Thanks again for all your time.

    Cheers

    ...Steve

    Was this answer helpful?

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

    Hi Steve,

    I've figured out a simpler and more reliable method:

    Sub Test()

    Dim i As Integer, xRefs As Variant

    xRefs = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)

    With Selection

      .Collapse wdCollapseEnd

      On Error Resume Next

      For i = 1 To UBound(xRefs)

        If ActiveDocument.ListParagraphs(i).Range = .Paragraphs(1).Range Then

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

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

          Exit Sub

        End If

      Next

    End With

    End Sub

    The ' .Collapse wdCollapseEnd' statement is there just in case you had one or more characters selected; this will avoid their deletion.


    Cheers,

    macropod MS MVP - Word

    Was this answer helpful?

    0 comments No comments