Search code examples
vbams-wordreference

fast reference in Microsoft Word with VBA


I have written two modules in the MS Word that can boost the speed of creat hyperlink for two words that they reference to each other:

enter image description here

This is useful specially when we want to reference many words. But my modules have a drawback. When I have many words, some of them may be repetitious. In the other words I have referenced the two words "book" in page1 and"boy"in page2 and now I want to reference the words "book"in page10 and "paper"in page20. With my modules this is impossible because book and book have one bookmark. Is there a way two solve this problem? or does someone have an idea?

These are my modules:

        Public N1 As String 
         Public N2 As String 
        Public Name2 As String 
        Public R2 As Range 
    Sub Macro1()
        N2 = Selection.Text
        Set R2 = Selection.Range
        Name2 = Trim(N2)
        N2 = Name2
        Name2 = Name2 & "a"
        With ActiveDocument.Bookmarks
            .Add Range:=Selection.Range, Name:=Name2
            .DefaultSorting = wdSortByName
            .ShowHidden = False
        End With
        With Selection.Range
            Selection.Font.Color = 16724787
            Selection.Font.UnderlineColor = wdColorAutomatic
            Selection.Font.Underline = wdUnderlineSingle
        End With 
        End Sub
    
    Sub Macro2()
        N1 = Selection.Text
        Dim Name1 As String
        Name1 = Trim(N1)
        N1 = Name1
        Name1 = Name1 & "b"
        With ActiveDocument.Bookmarks
            .Add Range:=Selection.Range, Name:=Name1
            .DefaultSorting = wdSortByName
            .ShowHidden = False
        End With
        With Selection.Range
            Selection.Font.Color = 16724787
            Selection.Font.UnderlineColor = wdColorAutomatic
            Selection.Font.Underline = wdUnderlineSingle
        End With
        ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:="", _
            SubAddress:=Name2, ScreenTip:="", TextToDisplay:=N1
        ActiveDocument.Hyperlinks.Add Anchor:=R2, Address:="", _
            SubAddress:=Name1, ScreenTip:="", TextToDisplay:=N2 
        End Sub

Solution

  • Use a dictionary to manage boomarknames. The following function will return the bookmarkname postfixed with a number. The dictionary is local to the function but is easily declared at the module level if so required.

    The "_" in the returned name makes it easy to retrieve the stem name by splitting at the "_".

    Public Function GetBookMarkName(byref ipName as string) as String
    
        Static mBookmarks as Scripting.Dictionary
        If mBookmarks is nothing then 
            Set mBookmarks = new scripting.dicitonary
        end if
    
        if mBookmarks.Exists(ipName) then
           mBookmarks.Item(ipName) = mBookmarks.Item(ipName)+1
        else
           mBookmarks.Add myName,1
        end if
        
         GetBookmarkName = ipName & "_" & cstr(mBookmarks.Item(ipName))
    
    end function