Search code examples
vbams-wordclickableword-2016

Macro to automate converting specifically formatted Strings to Hyperlinks in Word 2016


I work in a biblical commentary for a certain app. It is fed with a Word 2016 document. Now, in this Word document there are lots of references to Bible verses or passages.
The procedure to make a reference clickable is (lets put Mathew 1:10 as an example) writing "Mat 1.10" (without the quote marks), select it, right-click, select "Hyperlink..."(without the quote marks), and in the resulting Address field write "ref:Mat.1.10" (without the quote marks). A passage like "Mat 1.1-10" must be referenced as "ref:Mat.1.1-10".

How can I automate this so that after writing the verse/passage Word automatically references/inserts it? There would be no problem in writing the verse/passage surrounded by a specific character (°Mat 1.10°) so that Word understands that it is a portion it has to work with, afterwards I would delete the °s.

Notice that the empty space in the readable reference is replaced with a dot in the link: Mat 1.10 > ref:Mat.1.10

I played a lot with { HYPERLINK "ref:Mat.1.10" } trying to achieve results but no luck: it was not clickable.


Solution

  • In a quick test this worked for me:

    Sub LinkCreation()
        Dim rng As Range, txt As String, Cites As Collection
        Dim doc As Document
        
        Set doc = ActiveDocument  'the document to be processed
        Set Cites = AllCites(doc) 'get all ranges to be linked
        
        For Each rng In Cites     'process each matched range
            txt = Replace(rng.Text, "°", "") 'remove the markers
            rng.Text = txt
            'add the link (replace any space with a period)
            doc.Hyperlinks.Add Anchor:=rng, _
                    Address:="ref:" & Replace(txt, " ", "."), _
                    TextToDisplay:=txt
        Next rng
        
    End Sub
    
    'return a collection of all of the matched references
    Function AllCites(doc As Document) As Collection
        Dim rng As Range
        Set AllCites = New Collection
        Set rng = doc.Content
        With rng.Find
            .Text = "°*°" 'any text surrounded by °
            .MatchWildcards = True
            .Forward = True
            Do While .Execute() 'collect all the matches
                AllCites.Add rng.Duplicate
            Loop
        End With
    End Function