This is one of the issues of using Selection as opposed to Ranges. For a selection to be a selection you have to actually select it and that causes things to move around.
Assuming your heading texts are unique, the following macro will locate the heading text of the heading before the selected text, bookmark it with a name that reflects its content and apply a hyperlink to the selected text to that heading bookmark, without moving anything:
Code:
Sub Macro1()
'Graham Mayor - http://www.gmayor.com - 30/10/2016
Dim oHeading As Range
Dim oRng As Range
Dim strHeading As String
Set oRng = Selection.Range
Set oHeading = ActiveDocument.Range
oHeading.End = oRng.Start
With oHeading.Find
.Style = "Heading 2" 'The style of the heading text
Do While .Execute(Forward:=False)
oHeading.End = oHeading.End - 1
strHeading = oHeading.Text
strHeading = Replace(strHeading, Chr(32), Chr(95))
strHeading = "bm" & strHeading
oHeading.Bookmarks.Add strHeading
Exit Do
Loop
End With
ActiveDocument.Hyperlinks.Add _
Anchor:=oRng, _
Address:="", _
SubAddress:=strHeading, _
ScreenTip:="", _
TextToDisplay:=oRng.Text
lbl_Exit:
Set oRng = Nothing
Set oHeading = Nothing
Exit Sub
End Sub
The problems will start if that bookmark name clashes with a bookmark in your document, so it might be better to start by bookmarking all your headings with unique bookmark names and instead of deriving a bookmark name as above you use the name already associated with the heading in question.