none
How to Get crossreferances from a Word Document? RRS feed

  • Question

  • Hi,

    I have to make an .net application(in C#) which read a word file and find the count of crossreferances and their text. I checked with 

    document.GetCrossReferenceItems()

    but it gives me the list of strings to which I can set crossreferances. Suppose I have 3 paragraphs starts with X, Y, Z and the X paragraph contain a text say A which refers to paragraph Z I want to find Count as 1 and text as A, I also checked with

    document.Bookmarks.Count

    but it always gives me 0.

    (https://1drv.ms/w/s!Ah-Jh2Ok5SuHbKI1JRSJuv7S1jw) Here I uploaded a sample document which have 3 pages with 1 line of text  in each page. In the 1st page a text (Page 2) is refers to 2nd page. I need the "Page 2"(Highlighted in yellow) text from the 1st page.

    I need text form all reference type (numbered,heading,bookmark, footnote etc) of cross references

     


     


    Friday, October 14, 2016 1:37 PM

Answers

  • The following macro generates a table of all bookmarks at the end of either the active document or a new document, plus another table of all references to those bookmarks, each table including details of the story range names, page & line numbers and contents.

    Sub ListBkMrksAndRefs()
    Application.ScreenUpdating = False
    Dim oBkMrk As Bookmark, StrBkMk As String, StrXREf As String, StrStory As String
    Dim wdDocIn As Document, wdDocOut As Document, Rng As Range, Fld As Field, bHid As Boolean, Dest
    Dest = MsgBox(Prompt:="Output to New Document? (Y/N)", Buttons:=vbYesNoCancel, Title:="Destination Selection")
    If Dest = vbCancel Then Exit Sub
    Set wdDocIn = ActiveDocument
    If Dest = vbYes Then Set wdDocOut = Documents.Add
    If Dest = vbNo Then Set wdDocOut = wdDocIn
    With wdDocIn
      bHid = .Bookmarks.ShowHidden
      .Bookmarks.ShowHidden = True
      If .Bookmarks.Count > 0 Then
        StrBkMk = vbCr & "Bookmark" & vbTab & "Page" & vbTab & "Line" & vbTab & "Story" & Chr(160) & "Range" & vbTab & "Contents"
        StrXREf = vbCr & "Bookmark Ref" & vbTab & "Page" & vbTab & "Line" & vbTab & "Story" & Chr(160) & "Range" & vbTab & "Type" & vbTab & "Text"
        For Each oBkMrk In .Bookmarks
          Select Case oBkMrk.StoryType
            Case 1: StrStory = "Main text"
            Case 2: StrStory = "Footnotes"
            Case 3: StrStory = "Endnotes"
            Case 4: StrStory = "Comments"
            Case 5: StrStory = "Text frame"
            Case 6: StrStory = "Even pages header"
            Case 7: StrStory = "Primary header"
            Case 8: StrStory = "Even pages footer"
            Case 9: StrStory = "Primary footer"
            Case 10: StrStory = "First page header"
            Case 11: StrStory = "First page footer"
            Case 12: StrStory = "Footnote separator"
            Case 13: StrStory = "Footnote continuation separator"
            Case 14: StrStory = "Footnote continuation notice"
            Case 15: StrStory = "Endnote separator"
            Case 16: StrStory = "Endnote continuation separator"
            Case 17: StrStory = "Endnote continuation notice"
            Case Else: StrStory = "Unknown"
          End Select
          StrBkMk = StrBkMk & vbCr & oBkMrk.Name & vbTab & _
            oBkMrk.Range.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
            oBkMrk.Range.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & oBkMrk.Range.Text
        Next oBkMrk
        For Each Rng In .StoryRanges
          Select Case Rng.StoryType
            Case 1: StrStory = "Main text"
            Case 2: StrStory = "Footnotes"
            Case 3: StrStory = "Endnotes"
            Case 4: StrStory = "Comments"
            Case 5: StrStory = "Text frame"
            Case 6: StrStory = "Even pages header"
            Case 7: StrStory = "Primary header"
            Case 8: StrStory = "Even pages footer"
            Case 9: StrStory = "Primary footer"
            Case 10: StrStory = "First page header"
            Case 11: StrStory = "First page footer"
            Case 12: StrStory = "Footnote separator"
            Case 13: StrStory = "Footnote continuation separator"
            Case 14: StrStory = "Footnote continuation notice"
            Case 15: StrStory = "Endnote separator"
            Case 16: StrStory = "Endnote continuation separator"
            Case 17: StrStory = "Endnote continuation notice"
            Case Else: StrStory = "Unknown"
          End Select
          For Each Fld In Rng.Fields
            With Fld
              If (.Type = wdFieldRef) Then
                StrXREf = StrXREf & vbCr & Split(Trim(.Code.Text), " ")(1) & vbTab & _
                .Result.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
                .Result.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & "Ref"
              ElseIf (.Type = wdFieldPageRef) Then
                StrXREf = StrXREf & vbCr & Split(Trim(.Code.Text), " ")(1) & vbTab & _
                .Result.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
                .Result.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & "PageRef"
              End If
              StrXREf = StrXREf & vbTab & .Result
            End With
          Next
        Next
      Else
        MsgBox "There are no bookmarks in this document", vbExclamation
        GoTo Done
      End If
    End With
    With wdDocOut
      Set Rng = .Range.Characters.Last
      With Rng
        .Text = StrBkMk
        .Start = .Start + 1
        .ConvertToTable Separator:=vbTab
        With .Tables(1)
          .AutoFitBehavior wdAutoFitContent
          .Columns.Borders.Enable = True
          .Rows.Borders.Enable = True
          .Rows.First.Range.Font.Bold = True
        End With
      End With
      Set Rng = .Range.Characters.Last
      With Rng
        .Text = StrXREf
        .Start = .Start + 1
        .ConvertToTable Separator:=vbTab
        With .Tables(1)
          .AutoFitBehavior wdAutoFitContent
          .Columns.Borders.Enable = True
          .Rows.Borders.Enable = True
          .Rows.First.Range.Font.Bold = True
        End With
      End With
      .Bookmarks.ShowHidden = bHid
    End With
    Done:
    Set Rng = Nothing: Set wdDocIn = Nothing: Set wdDocOut = Nothing
    Application.ScreenUpdating = True
    End Sub

    Note that line numbers only apply to the main story. Other stories will return -1.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, October 17, 2016 10:39 AM
  • Hi Madan,

    I fall in that exact questions last days. Here is my experience:

    Cross references you are looking for are fields whose Type == Word.WdFieldType.wdFieldRef

    So if you list all document fields, you may filter (methods can be implemented as extensions for Range):

    1. Get all fields (as a list)

    List<Word.Field> list = new List<Word.Field>();

    var fields = range.Fields;
    if(fields == null)
    return list;

    foreach(Word.Field f in fields)
    list.Add(f);

    return list

    2. Get cross references:

    List<Word.Field> allFields = GetFieldList(); // above code
    return allFields == null ? list :  allFields.Where(item => item.Type == Word.WdFieldType.wdFieldRef);

    Hope this may help

    Tuesday, October 18, 2016 7:34 AM

All replies

  • Hi,

    How do you insert the cross-reference? Could you please share with us the detail steps or information?

    If possible, I suggest you share a sample document with cross-reference, so that we could help you check how to retrieve the number and text.

    You could upload the document in the OneDrive and paste the URL here.

    Thanks for your understanding.

    Regards,

    Celeste

    Monday, October 17, 2016 5:39 AM
    Moderator
  • You need to be clearer about your requirements.

    Do you want to get an output containing all bookmarked content, or cross-references to those bookmarks? The latter may contain the bookmarked text, its page #, above/below, or could be in the form of a hyperlink that displays either the bookmarked text or a prompt such as 'Click Here'. Word also has two kinds of bookmarks - visible and hidden. Hidden bookmarks are usually used by Word for cross-references to headings etc., including for the creation of Tables of Contents and the like.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, October 17, 2016 7:17 AM
  • @Celeste Thanks for your time, kindly check my updated question 
    Monday, October 17, 2016 9:20 AM
  •  @Paul, Thanks for your time, kindly check my updated question 
    Monday, October 17, 2016 9:21 AM
  • The following macro generates a table of all bookmarks at the end of either the active document or a new document, plus another table of all references to those bookmarks, each table including details of the story range names, page & line numbers and contents.

    Sub ListBkMrksAndRefs()
    Application.ScreenUpdating = False
    Dim oBkMrk As Bookmark, StrBkMk As String, StrXREf As String, StrStory As String
    Dim wdDocIn As Document, wdDocOut As Document, Rng As Range, Fld As Field, bHid As Boolean, Dest
    Dest = MsgBox(Prompt:="Output to New Document? (Y/N)", Buttons:=vbYesNoCancel, Title:="Destination Selection")
    If Dest = vbCancel Then Exit Sub
    Set wdDocIn = ActiveDocument
    If Dest = vbYes Then Set wdDocOut = Documents.Add
    If Dest = vbNo Then Set wdDocOut = wdDocIn
    With wdDocIn
      bHid = .Bookmarks.ShowHidden
      .Bookmarks.ShowHidden = True
      If .Bookmarks.Count > 0 Then
        StrBkMk = vbCr & "Bookmark" & vbTab & "Page" & vbTab & "Line" & vbTab & "Story" & Chr(160) & "Range" & vbTab & "Contents"
        StrXREf = vbCr & "Bookmark Ref" & vbTab & "Page" & vbTab & "Line" & vbTab & "Story" & Chr(160) & "Range" & vbTab & "Type" & vbTab & "Text"
        For Each oBkMrk In .Bookmarks
          Select Case oBkMrk.StoryType
            Case 1: StrStory = "Main text"
            Case 2: StrStory = "Footnotes"
            Case 3: StrStory = "Endnotes"
            Case 4: StrStory = "Comments"
            Case 5: StrStory = "Text frame"
            Case 6: StrStory = "Even pages header"
            Case 7: StrStory = "Primary header"
            Case 8: StrStory = "Even pages footer"
            Case 9: StrStory = "Primary footer"
            Case 10: StrStory = "First page header"
            Case 11: StrStory = "First page footer"
            Case 12: StrStory = "Footnote separator"
            Case 13: StrStory = "Footnote continuation separator"
            Case 14: StrStory = "Footnote continuation notice"
            Case 15: StrStory = "Endnote separator"
            Case 16: StrStory = "Endnote continuation separator"
            Case 17: StrStory = "Endnote continuation notice"
            Case Else: StrStory = "Unknown"
          End Select
          StrBkMk = StrBkMk & vbCr & oBkMrk.Name & vbTab & _
            oBkMrk.Range.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
            oBkMrk.Range.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & oBkMrk.Range.Text
        Next oBkMrk
        For Each Rng In .StoryRanges
          Select Case Rng.StoryType
            Case 1: StrStory = "Main text"
            Case 2: StrStory = "Footnotes"
            Case 3: StrStory = "Endnotes"
            Case 4: StrStory = "Comments"
            Case 5: StrStory = "Text frame"
            Case 6: StrStory = "Even pages header"
            Case 7: StrStory = "Primary header"
            Case 8: StrStory = "Even pages footer"
            Case 9: StrStory = "Primary footer"
            Case 10: StrStory = "First page header"
            Case 11: StrStory = "First page footer"
            Case 12: StrStory = "Footnote separator"
            Case 13: StrStory = "Footnote continuation separator"
            Case 14: StrStory = "Footnote continuation notice"
            Case 15: StrStory = "Endnote separator"
            Case 16: StrStory = "Endnote continuation separator"
            Case 17: StrStory = "Endnote continuation notice"
            Case Else: StrStory = "Unknown"
          End Select
          For Each Fld In Rng.Fields
            With Fld
              If (.Type = wdFieldRef) Then
                StrXREf = StrXREf & vbCr & Split(Trim(.Code.Text), " ")(1) & vbTab & _
                .Result.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
                .Result.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & "Ref"
              ElseIf (.Type = wdFieldPageRef) Then
                StrXREf = StrXREf & vbCr & Split(Trim(.Code.Text), " ")(1) & vbTab & _
                .Result.Characters.First.Information(wdActiveEndAdjustedPageNumber) & vbTab & _
                .Result.Information(wdFirstCharacterLineNumber) & vbTab & StrStory & vbTab & "PageRef"
              End If
              StrXREf = StrXREf & vbTab & .Result
            End With
          Next
        Next
      Else
        MsgBox "There are no bookmarks in this document", vbExclamation
        GoTo Done
      End If
    End With
    With wdDocOut
      Set Rng = .Range.Characters.Last
      With Rng
        .Text = StrBkMk
        .Start = .Start + 1
        .ConvertToTable Separator:=vbTab
        With .Tables(1)
          .AutoFitBehavior wdAutoFitContent
          .Columns.Borders.Enable = True
          .Rows.Borders.Enable = True
          .Rows.First.Range.Font.Bold = True
        End With
      End With
      Set Rng = .Range.Characters.Last
      With Rng
        .Text = StrXREf
        .Start = .Start + 1
        .ConvertToTable Separator:=vbTab
        With .Tables(1)
          .AutoFitBehavior wdAutoFitContent
          .Columns.Borders.Enable = True
          .Rows.Borders.Enable = True
          .Rows.First.Range.Font.Bold = True
        End With
      End With
      .Bookmarks.ShowHidden = bHid
    End With
    Done:
    Set Rng = Nothing: Set wdDocIn = Nothing: Set wdDocOut = Nothing
    Application.ScreenUpdating = True
    End Sub

    Note that line numbers only apply to the main story. Other stories will return -1.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, October 17, 2016 10:39 AM
  • can these thing achieve in .net(c#)
    Monday, October 17, 2016 12:06 PM
  • You will need to do the conversion - I don't know C#.

    Cheers
    Paul Edstein
    [MS MVP - Word]

    Monday, October 17, 2016 12:12 PM
  • Hi Madan,

    I fall in that exact questions last days. Here is my experience:

    Cross references you are looking for are fields whose Type == Word.WdFieldType.wdFieldRef

    So if you list all document fields, you may filter (methods can be implemented as extensions for Range):

    1. Get all fields (as a list)

    List<Word.Field> list = new List<Word.Field>();

    var fields = range.Fields;
    if(fields == null)
    return list;

    foreach(Word.Field f in fields)
    list.Add(f);

    return list

    2. Get cross references:

    List<Word.Field> allFields = GetFieldList(); // above code
    return allFields == null ? list :  allFields.Where(item => item.Type == Word.WdFieldType.wdFieldRef);

    Hope this may help

    Tuesday, October 18, 2016 7:34 AM