• Automatic cross referencing in a large document

    Home » Forums » AskWoody support » Productivity software by function » MS Word and word processing help » Automatic cross referencing in a large document

    • This topic has 7 replies, 3 voices, and was last updated 13 years ago.
    Author
    Topic
    #482917

    Hi geniuses!

    I’ve done some extensive searching on this site, and the web generally, and can’t seem to find anything relevant (or even anyone asking the same question, which is odd!).

    Essentially, I work in the legal industry, and often deal with very large documents full of clauses. Often, I will get a request to cross reference these very large documents. This usually takes me quite a long time, because I have so far not been able to find a method to have Word cross reference automatically.

    What I would like to be able to do, is run a macro which will search for the word “clause” and then for whatever number/letter comes after that, it would insert a cross reference. So, “clause 2(a)(i)” would be found, and the macro would insert a cross reference over 2(a)(i) to paragraph 2(a)(i) (I don’t need the word “clause” included in the cross reference, just the number/letter).

    All of these documents always have correct outline numbering, and clause is always followed by a space, and then the reference with no spaces, and then either a punctuation mark, or a space (ie, clause 2(a)(i) OR clause 2(a)(i), OR clause 2(a)(i). OR clause 2(a)(i): OR clause 2(a)(i); etc).

    Does this make any sense at all? And is it even possible? I would just really love to be able to cross reference these enormous documents in one click, instead of spending hours doing them all individually.

    Thanks!

    Caracolesa

    Viewing 4 reply threads
    Author
    Replies
    • #1330385

      Are the original paragraphs you want the cross-reference to lead to created using Word’s outline numbering? And by “cross-reference” do you mean making the text hyperlink?

      If so, when you enter the text that refers to clause 2(a)(i) you can do it by entering it as a cross-reference to the original location. In the Enter cross-reference box, select Numbered Items and Paragraph Number.

      If you are faced with a doc where someone hand-entered all the references originally, you’re in macro-land. It wouldn’t be a simple macro, either.

      – Jessica

      • #1330507

        Thanks for the reply, Jess! I’ve obviously not explained myself very well.

        Yes, the document uses Word’s outline numbering, and yes, I could go through the 1000+ clause references and cross-reference them manually (by selecting 2(a)(i) (for example), going to Reference -> Cross Reference -> Select numbered item 2(a)(i) in the list -> Insert reference to paragraph number).

        However, I’m trying to avoid that, because it’s very time consuming. Essentially, I want to be able to open a document, and click on a button, and have it turn all clause references into cross-references automatically. Does that make sense? It would search through the document, and find any instance of the word “clause” followed by any alphanumeric, and then reference it to the correct outline numbered paragraph.

        The current document I’m working on has over 1,000 clause references to cross-reference, and it’s not a one-off. I regularly get such documents, so a macro such as this would literally save hours of my time.

        If it assists, the outline numbering used is always:

        1.
        1.1
        (a)
        (i)
        (A)
        (1)

        and clauses are always referenced with the word “clause” followed by a space, followed by the alphanumeric without spaces in between – i.e.: clause 2(a)(i), or clause 1.13(a), or clause 24(a)(iii)(C), etc.

        Thanks for your time! Let me know if this hasn’t made any sense.

        Caracolesa

        • #1330523

          Ok. You’re definitely in macro-land. I think I can see how to do it. You would use document.getCrossReferenceItems to get an array of the numbered clauses, then loop through all the numbered clauses, search for any text matching the clause number elsewhere in the doc, and use selection.insertcrossreference to replace the text with a cross-ref to the numbered clause.

          Not trivial but a macro jockey with time on his or her hands could do it. I wish I had the time to play with this.

          Oh, and for the future you might want to bribe whoever creates the documents to insert the clause references as automated cross-refs to begin with.

          – Jessica

    • #1330517

      Questions similar to this have been asked before (every 3-4 years) and basically the stock response is along the lines of ‘It is a good idea and it would save considerable time but it is a lot of work to code and I’m not doing it unless I have the specific need or am being paid for it’.

      In my opinion the ideal solution would be to add an option to the menu that pops up when you right click and drag a selection. The ‘Link Here’ option that exists in that menu creates a hyperlink to that selection. This is almost there but falls short in a key area – It is a Link field, not a Ref field so you can’t link to the paragraph number of the selection. My idea is that we would add another option in this menu that let you put in a Ref field to the selection and maybe hold down a modifier Key (eg Ctrl) at the same time to make this Ref field to the paragraph number. I think that type of solution would be the slickest implementation but it requires a macro and customisation of the shortcut menu to provide the option.

      I do have a fallback solution that we have used to build a complete table of cross-references to all headings (or numbered paragraphs) in the document. This gets inserted into the back of the current document and can then be used to copy paste into the main part of the document as required. This would do the task but not be the ideal solution for you.

      Code:
      Public Sub BuildSeeAlsoLibrary()
        Dim aDoc As Document, sRef As String
        Dim rng As Range
        Dim astrHeadings As Variant
        Dim strText As String
        Dim intLevel As Integer
        Dim intItem As Integer
        
        Set aDoc = ActiveDocument
        
        ‘ Content returns only the main body of the document, not the headers and footer.
        astrHeadings = aDoc.GetCrossReferenceItems(wdRefTypeHeading)   ‘wdRefTypeNumberedItem
        Set rng = aDoc.Content
        rng.Collapse Direction:=wdCollapseEnd
        aDoc.Tables.Add Range:=rng, NumRows:=1, NumColumns:=3
        
        For intItem = LBound(astrHeadings) To UBound(astrHeadings)
          ‘ Get the text and the level.
          strText = Trim$(astrHeadings(intItem))
          intLevel = GetLevel(CStr(astrHeadings(intItem)))
          If intLevel < 7 Then
            With aDoc.Tables(aDoc.Tables.Count)
              .Rows.Add
              Set rng = .Cell(.Rows.Count, 1).Range
              rng.Collapse wdCollapseStart
              rng.InsertCrossReference ReferenceType:=wdRefTypeHeading, ReferenceKind:=wdNumberFullContext, _
                    ReferenceItem:=intItem, InsertAsHyperlink:=True
              Debug.Print .Cell(.Rows.Count, 1).Range.Fields(1).Code
              sRef = .Cell(.Rows.Count, 1).Range.Fields(1).Code
              sRef = Replace(sRef, " w", "")
              Debug.Print sRef
              Set rng = .Cell(.Rows.Count, 2).Range
              rng.Collapse wdCollapseStart
              aDoc.Fields.Add Range:=rng, Text:=sRef, Type:=wdFieldEmpty
            End With
          End If
        Next intItem
      End Sub
      
      
      Private Function GetLevel(strItem As String) As Integer
          ' Return the heading level of a header from the array returned by Word.
          Dim strTemp As String
          Dim strOriginal As String
          Dim intDiff As Integer
          strOriginal = RTrim$(strItem) ' Get rid of all trailing spaces.
          strTemp = LTrim$(strOriginal) ' Trim leading spaces, and then compare with the original.
          intDiff = Len(strOriginal) – Len(strTemp) ' Subtract to find the number of leading spaces in the original string.
          GetLevel = (intDiff / 2) + 1
      End Function
    • #1330528

      What about using document.getCrossReferenceItems to get an array of the numbered clauses, then loop through all the numbered clauses, search for any text matching the clause number elsewhere in the doc, and use selection.insertcrossreference to replace the text with a cross-ref to the numbered clause (with options set for showing the number only)?

      Not trivial but a macro jockey with time on his or her hands could do it. I wish I had the time to play with this.

      Oh, and for the future you might want to bribe whoever creates the documents to insert the clause references as automated cross-refs to begin with.

      – Jessica

    • #1330530

      Thanks Andrew – I guess that’s why I didn’t find any references to it – I was only searching through the last year. Thanks for your solution. It will make it somewhat quicker. Out of interest, any idea what it would cost to pay someone to code it?

      Jess – asking secretaries in this place to do such a simple task?! Are you insane? I’m being facetious, but seriously, I have no idea how some of these people even get jobs as secretaries, they know so little about Word. And of course, if it takes an extra 2 seconds, then of course they’re far too busy to be bothered with such a thing. They’d rather just send it on to someone else to fix for them.

    • #1330539

      I would estimate it would be around 4-6 hours work to come up with a workable solution to your original request of doing the search/replace type function.

      The real trick is to get a good enough series of wildcard searches to find all the possible paragraph number variants that a ‘legal document’ might have eg
      1.2.3.1
      1.2(a)
      1.3.i
      1-2.3.1
      Appendix A-1

      I would probably attempt this from the other direction ie. build an array of all the paragraph numbers in a document, do a search for each unique array member in the body of the document and if found replace it with a cross-ref. This methodology would remove the likelihood of missing a number pattern you hadn’t catered for but would fail where the paragraph number was hard-coded.

      Another complication of any solution is where the paragraph number is implied based on a parent paragraph. This may be a show-stopper if your docs are formatted this way.
      eg.
      1.1 some text
      (a) some more text

      text see clause 1.1(a) for details

      My previously suggested ‘ideal’ solution is not going to address your search/replace question. It is more focused on making the manual addition of cross-references easier for the secretary to do themselves during authoring rather than retrofitting an existing document.

    Viewing 4 reply threads
    Reply To: Automatic cross referencing in a large document

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: