Hack 43 Cross-Reference Automatically![]() ![]() references, particularly in a lengthy document, can be frustrating because it shows you only a few headings at a time. This hack shows you how to create references automatically, without a visit to the dialog.Whoever decided that the Cross-reference dialog in Word (Insert Insert should display only nine items at a time clearly didn't have your best interests in mind. Most lengthy documents include more than nine headings, captions, or other items to reference.In many cases, creating a cross-reference means converting static text into a dynamic reference by selecting it, then replacing it with the corresponding item from the Cross-reference dialog (as shown in Figure 4-27). But since there's that nine-item limit, you're in for some serious scrolling if you need to make many references. In a Sisyphean spiral, the longer your document is, the more references you likely need, and the longer it will take to find each item in that teeny, tiny list. Figure 4-27. Only nine items at a time are visible in the Cross-reference dialog![]() cross-references to headings. In each case, the selected text is compared to the headings in a document, trying to find a match and create a cross-reference. 4.18.1 Referencing the Way Word DoesThe procedure shown in this section uses Word VBA's GetCrossReferenceItems method, which returns a list of potential reference targets in a document. Because Word continually updates and indexes this list, accessing it is very fast. This code runs significantly faster than the code in the next section, but that speed comes at a price: you're limited to creating cross-references to items that Word considers potential targets, such as headings that use one of the built-in heading styles. If you've also got a different kind of heading style in your document, such as SidebarTitle, those headings don't "count" as possible reference targets.Place this macro in the template of your choice [Hack #50] and either run it from the Tools dialog or put a button for it on a menu or toolbar [Hack #1].If your current selection includes more than one paragraph, the macro exits without taking any action. Sub InsertAutoXRef( )There are two important limitations to note about this code. First, if multiple headings match the selected text, the code creates a reference to the first match and ignores subsequent matches. This limitation is a problem if you have multiple headings with the same text, such as "The Code," used throughout this book.Second, the code offers no protection against creating a self-reference. If the match found by the code is the text you've selected, the reference that's created will replace the text it's supposed to reference, resulting in a broken reference, as shown in Figure 4-28. Figure 4-28. Self-referencing creates a broken reference![]() references from the Word Cross-reference dialog. When you create a self-reference, Word displays a message telling you the reference is emptybut only after the text has been deleted. 4.18.2 A Better Way to ReferenceThis method won't match the speed offered by the code shown above, but its flexibility makes it a better starting point for hacking your own solutions.Rather than looking only at paragraphs that use one of Word's built-in heading styles, this code examines every paragraph in the document, looking for a match to the selected text. That means you can easily create a reference to a heading that uses a custom paragraph style, such as SidebarTitle.Unlike the code in the previous section, this procedure also checks to be sure the match it's found isn't the selected text, avoiding the possibility of a self-reference.This code is divided into five separate procedures: the MakeAutoXRef procedure and four supporting procedures, each of which performs an operation needed to create the reference. Place all five procedures in the template of your choice [Hack #50] and run the one named MakeAutoXRef to create a reference in place of the selected text.The first procedure, named MakeAutoXRef, is shown first. In conjunction with the supporting procedures shown afterward, it examines each paragraph in the document. If it finds one that matches the selected text, it creates a bookmark around the match and then replaces the selected text with a reference pointing to the bookmark. If the matched paragraph has already been referenced elsewhere, the existing bookmark is used. Sub MakeAutoXRef( )The code shown in bold is the part of the procedure that actually creates the reference. Note that it's very similar to part of the code shown in the previous section. 4.18.2.1 The supporting proceduresThe following function removes from a string characters that Word won't allow in bookmark names (except for spaces, which are replaced by underscores in a different procedure): Function RemoveInvalidBookmarkCharsFromString(ByVal str As String) As StringThe next function takes a string and turns it into a valid bookmark name, including prefacing it with "XREF" for easier identification and adding in a five-digit random number [Hack #68] to ensure that it's unique.In addition, the function replaces underscores with spaces. So, for example, the heading "Foo the bar" would be converted into something like "XREF56774_Foo_the_bar"a bit easier to work with than the "_Ref45762234"-style names that Word assigns to its own cross-reference bookmarks. Function ConvertStringRefBookmarkName(ByVal str As String) As StringThis next function just determines a paragraph's index in the document (e.g., the second paragraph in the document has an index of 2): Function GetParagraphIndex(para As Paragraph) As LongThe final function creates cross-reference bookmarks in paragraphs that do not contain bookmarks and returns the bookmark name for use in the cross-reference. If the paragraph already has a cross-reference bookmark, it simply returns the existing bookmark name for use in the cross-reference. Function GetOrSetXRefBookmark(para As Paragraph) As String 4.18.2.2 Running the hackThis hack wouldn't be much of a time-saver if you had to go through a menu to run it. This code is most helpful when assigned to a keyboard shortcut.To assign a macro to a keyboard shortcut, select Tools changes in the same template in which you installed the code. In the Categories column, select Macros, and in the Commands column, select MakeAutoXRef. Choose and assign a keyboard shortcut using the dialog. |