MS Word: Macro that creates bibliography bookmarks and then links corresponding text citations to them

125 Views Asked by At

I need to link my in-text citations to their corresponding entries in the bibliography list (IEEE style, e.g. [1], [2], [3], etc.).

Surprisingly, this is not something that is automated when exporting to PDF (as with footnotes and endnotes) when using the bibliography tool in Word.

So, I'm trying out macros/VBA to automate this for me, as I work with documents with 50+ references that need hyperlinks.

I'm a total newbie, but I'm trying to learn.

First, I have a macro that turns the in-text citation labels ([1], [2], etc.) to static text. This works fine, and enables me to edit the in-text citations before exporting to PDF. However, the most time consuming work is to link up the citations one by one.

So, after making the citations static text, I want a macro that does the following:

  • Set the range to the bibliography section (section 4)
  • Search the range for any numbers in brackets ([1], [2], etc.)
  • Once a number in brackets are found, create a bookmark for that number, where the name of the bookmark is "Reference"+number. Do this for all the numbers in brackets in the given range (section 4).

Then, I want the macro (or another macro) to

  • set the range to section 2 and 3 (the main document text)
  • search the range for any numbers in brackets ([1], [2], etc.)
  • once a number in brackets are found, insert a hyperlink in the number and brackets, where the hyperlink adress is the corresponding bookmark created earlier (e.g. [1] = "Reference1" bookmark, [2] = "Reference2" bookmark etc.)

Could anyone give me some guidance (or correct my code) to help with what I want to achieve?

This is my VBA code as of now, and I cannot get it to function. I run it, but nothing happens - it seems like it won't run, but I get no errors:

Sub CreateBookmarksAndHyperlinks() 

    ' Set the range to bibliography section (section 4) 

    Dim biblioRange As Range 

    Set biblioRange = ActiveDocument.Sections(4).Range 

     

    ' Search for numbers in brackets and create bookmarks 

    With biblioRange.Find 

        .ClearFormatting 

        .Text = "\[[0-9]+\]" ' Search for [1], [2], etc. 

        .MatchWildcards = True 

        .Wrap = wdFindStop 

        Do While .Execute 

            Dim foundTextBiblio As String 

            foundTextBiblio = Mid(biblioRange.Text, 2, Len(biblioRange.Text) - 2) ' Extract number between brackets 

            biblioRange.Bookmarks.Add "Reference" & foundTextBiblio, biblioRange 

        Loop 

    End With 

     

    ' Set the range to main document text (sections 2 and 3) 

    Dim mainRange As Range 

    Set mainRange = ActiveDocument.Range(Start:=ActiveDocument.Sections(2).Range.Start, End:=ActiveDocument.Sections(3).Range.End) 

     

    ' Search for numbers in brackets and insert hyperlinks 

    With mainRange.Find 

        .ClearFormatting 

        .Text = "\[[0-9]+\]" ' Search for [1], [2], etc. 

        .MatchWildcards = True 

        .Wrap = wdFindStop 

        Do While .Execute 

            Dim foundTextMain As String 

            foundTextMain = Mid(mainRange.Text, 2, Len(mainRange.Text) - 2) ' Extract number between brackets 

            If mainRange.Bookmarks.Exists("Reference" & foundTextMain) Then 

                ' Insert hyperlink using the corresponding bookmark 

                ActiveDocument.Hyperlinks.Add Anchor:=mainRange, Address:="", SubAddress:="Reference" & foundTextMain, TextToDisplay:=mainRange.Text 

            End If 

        Loop 

    End With 

End Sub
2

There are 2 best solutions below

0
On BEST ANSWER
  • @ stands for one or more chars in Word searching (@jonsson comments it before my answer)
  • Bookmarks are in section 4, mainRange.Bookmarks.Exists should be ActiveDocument.Bookmarks.Exists
  • Hyperlinks.Add collapses mainRange to its start, adding mainRange.Move to move the range.
Option Explicit

Sub CreateBookmarksAndHyperlinks()
    ' Set the range to bibliography section (section 4)
    Dim biblioRange As Range
    Set biblioRange = ActiveDocument.Sections(4).Range
    ' Search for numbers in brackets and create bookmarks
    With biblioRange.Find
        .ClearFormatting
        .Text = "\[[0-9]@\]" ' Search for [1], [2], etc.
        .MatchWildcards = True
        .Wrap = wdFindStop
        Do While .Execute
            Dim foundTextBiblio As String
            foundTextBiblio = Mid(biblioRange.Text, 2, Len(biblioRange.Text) - 2) ' Extract number between brackets
            biblioRange.Bookmarks.Add "Reference" & foundTextBiblio, biblioRange
        Loop
    End With
    ' Set the range to main document text (sections 2 and 3)
    Dim mainRange As Range, iEnd As Long
    iEnd = ActiveDocument.Sections(3).Range.End
    Set mainRange = ActiveDocument.Range(Start:=ActiveDocument.Sections(2).Range.Start, End:=iEnd)
    ' Search for numbers in brackets and insert hyperlinks
    With mainRange.Find
        .ClearFormatting
        .Text = "\[[0-9]@\]" ' Search for [1], [2], etc.
        .MatchWildcards = True
        .Forward = True
        .Wrap = wdFindStop
        Do While .Execute
            If mainRange.Start > iEnd Then Exit Do
            Dim foundTextMain As String, iLen As Long
            iLen = Len(mainRange.Text)
            foundTextMain = Mid(mainRange.Text, 2, iLen - 2) ' Extract number between brackets
            If ActiveDocument.Bookmarks.Exists("Reference" & foundTextMain) Then
                ' Insert hyperlink using the corresponding bookmark
                ActiveDocument.Hyperlinks.Add Anchor:=mainRange, Address:="", SubAddress:="Reference" & foundTextMain, TextToDisplay:=mainRange.Text
            End If
            mainRange.Move Unit:=Word.wdCharacter, Count:=iLen
        Loop
    End With
End Sub
0
On

Thank you so much, both of you!

The adjustments you provided, taller, worked like a charm! I am extremely grateful.

Now, If anyone else is trying to google this (I know I did, and I couldn't find a solution), this is what I ended up with. It is based on a document that uses IEEE style references with Word's bibliography function.

The document has 6 sections. The 6th section contains the reference list/bibliography.

First, run this macro to make the in-text citations to static text. This is necessary to apply hyperlinks to them:

Sub ConvertCitationToStaticText()
Dim iFld As Field
Dim oRng As Range
For Each iFld In ActiveDocument.Range.Fields
    If iFld.Type = wdFieldCitation Then
        iFld.Select
        Set oRng = Selection.Range
        oRng.Start = oRng.Start - 1
        oRng.End = oRng.End + 1
        oRng.Select
        oRng.Text = iFld.Result
    End If
Next iFld
End Sub

Then, run the following macro.

  • adjust the bibliography list section (where bookmarks are created)
  • adjust the main text section range (start and end of where the in-text citations are found and hyperlinked)

In my case, the bibliography was located in section 6 and the main text was found in sections 1-5:

Sub CreateBookmarksAndHyperlinks()
    ' Set the range to bibliography section (section number where the bibliography list is)
    Dim biblioRange As Range
    Set biblioRange = ActiveDocument.Sections(6).Range
    ' Search for numbers in brackets and create bookmarks
    With biblioRange.Find
        .ClearFormatting
        .Text = "\[[0-9]@\]" ' Search for [1], [2], etc.
        .MatchWildcards = True
        .Wrap = wdFindStop
        Do While .Execute
            Dim foundTextBiblio As String
            foundTextBiblio = Mid(biblioRange.Text, 2, Len(biblioRange.Text) - 2) ' Extract number between brackets
            biblioRange.Bookmarks.Add "Reference" & foundTextBiblio, biblioRange
        Loop
    End With
    ' Set the range to main document text (e.g. from sections 1 to 5)
    Dim mainRange As Range, iEnd As Long
    iEnd = ActiveDocument.Sections(5).Range.End
    Set mainRange = ActiveDocument.Range(Start:=ActiveDocument.Sections(1).Range.Start, End:=iEnd)
    ' Search for numbers in brackets and insert hyperlinks
    With mainRange.Find
        .ClearFormatting
        .Text = "\[[0-9]@\]" ' Search for [1], [2], etc.
        .MatchWildcards = True
        .Forward = True
        .Wrap = wdFindStop
        Do While .Execute
            If mainRange.Start > iEnd Then Exit Do
            Dim foundTextMain As String, iLen As Long
            iLen = Len(mainRange.Text)
            foundTextMain = Mid(mainRange.Text, 2, iLen - 2) ' Extract number between brackets
            If ActiveDocument.Bookmarks.Exists("Reference" & foundTextMain) Then
                ' Insert hyperlink using the corresponding bookmark
                ActiveDocument.Hyperlinks.Add Anchor:=mainRange, Address:="", SubAddress:="Reference" & foundTextMain, TextToDisplay:=mainRange.Text
            End If
            mainRange.Move Unit:=Word.wdCharacter, Count:=iLen
        Loop
    End With
End Sub