How to Traverse Through a Word Doc’s Footnotes/Endnotes with Visual Basic

My husband was nearing the deadline to turn in his recent book, and he was under a lot of pressure to finish a detailed manuscript preparation checklist. I offered to help with any tasks that didn’t need his direct involvement to complete. One of the bigger requests was that I go through all the book’s endnotes, tag all archival sources that were referenced, and then log the manuscript page the endnote was connected to.

Come the weekend, I found that the book had almost a thousand endnotes! It took me over ten minutes to manually get through just fifteen endnotes, and by the end of it, I was finding the task insurmountable. There had to be another way!

The developer in me immediately wanted to automate going through the endnotes. I decided to spend some time investigating how to parse a Word doc (time-boxing it to a couple of hours). With a little digging, I realized that Visual Basic can accomplish almost any task in a Word document if you learn its language.

The concept of traversing through a list and finding a match is fairly easy; the time-consuming part was learning Visual Basic’s syntax. After spending an hour going through Visual Basic documentation and playing with the syntax, I got it to work. I felt real satisfaction in running the program and instantly getting accurate results, especially knowing that it would have taken hours of work if there was no way to automate this task.

Here are a few things that stood out to me when learning the basics (no pun intended) of Visual Basic.

1. Getting Started

After opening the Word doc, click on “Visual Basic” under the “Developer” tab. After Visual Basic is launched, there’s an area for inputting the code:

2. Declaring Variables

Declare the variable with its type following As:

'Variables for parsing
'For reading each endnote
Dim endnote As Endnote
Dim endnoteLine As String

'The location where we find the matching index
'the index is -1 if not found
Dim existIndex As Integer

'Storing the last found page to avoid duplicates
Dim lastPrinted As Integer
Dim endnotePageNumber As Integer

'The word that we want to find inside each footnote
Dim searchWord As String

3. Assigning Values

I’m looking for a specific archival reference (abbreviated here as “JARC”), and can easily change the variable when I’m searching for another archive or phrase.

searchWord = "JARC"

4. For Loop

Traversing through all possible endnotes with a for loop, the only thing to note is the Next necessary for the For Each loop and End If for all If statements.

For Each endnote In ActiveDocument.Endnotes
  'storing each endnote's text to search for word
  endnoteLine = endnote.Range.Text
  'using InStr to method to see if endnote contains the word
  existIndex = InStr(1, endnoteLine, searchWord)
  'If we find the matching word 
  'then find and print the adjusted page number it appears in
  If (existIndex > 0) Then
    'looking up an adjusted page number vs regular page number
    'only because chapters were separated into diff docs
    endnotePageNumber = endnote.Reference.Information(wdActiveEndAdjustedPageNumber)
    'checking to see if we have already found an endote on this page already
    If (lastPrinted <> endnotePageNumber) Then
      'display the page number with a comma into the debug window'
      Debug.Print CStr(endnotePageNumber) + ", ";
    End If
  'setting the last page that was found
  lastPrinted = endnotePageNumber
  End If
Next

Code

Here’s the complete code without comments. What is convenient here is that if the document had footnotes instead of endnotes, you could simply swap Endnote with Footnote wherever appropriate.

Sub goThroughEndnotes()

  Dim endnote As Endnote
  Dim endnoteLine As String
  Dim existIndex As Integer
  Dim lastPrinted As Integer
  Dim endnotePageNumber As Integer
  Dim searchWord As String

  searchWord = "JARC"

  For Each endnote In ActiveDocument.Endnotes
    endnoteLine = endnote.Range.Text
    existIndex = InStr(1, endnoteLine, searchWord)
    If (existIndex > 0) Then
      endnotePageNumber = endnote.Reference.Information(wdActiveEndAdjustedPageNumber)
      If (lastPrinted <> endnotePageNumber) Then
        Debug.Print CStr(endnotePageNumber) + ", ";
      End If
      lastPrinted = endnotePageNumber
    End If
  Next

End Sub

Given that this code easily saved me hours, I truly hope it will save another writer similar time and stress if they need to search and log all their footnotes or endnotes!