Hyperlinked text in Word footers to a selected bookmark - vba

I wanted a custom footer in all my documents with a hyperlinked text to a bookmark in same document. i.e. 'Top Of Document' kind of link in all the footers. I had to collect information for all over the places to achieve this much. and wanted to share here so others do not have to fight for this thing all at once.
So far from all the question & suggestions from stackoverflow and other sites, I have achieved this much-
Created a macro to create a bookmark automatically, of a selected text in document.
Bookmark will be re-created (delete and create) if its already present
Macro will add a new footer with page number and a text with delimiter (i.e. / Hit Overview).
Now I want to create this text in footer a HyperLink to the bookmark. code is simple. but i guess i am doing something wrong, tried by creating a HyperLink object. but not working. please suggest something.
Here is the macro function-
Sub InsertFootnote()
Const wdAlignPageNumberCenter = 1
Dim varNumberPages As Variant
varNumberPages = ActiveDocument.Content.Information(wdActiveEndAdjustedPageNumber)
' Delete bookmark if any with this name
If ActiveDocument.Bookmarks.Exists("HitOverviewMac") = True Then
ActiveDocument.Bookmarks("HitOverviewMac").Delete
End If
' Create a Bookmark to the selected text
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:="HitOverviewMac"
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
Dim mHlink As Hyperlink
Dim i As Long
For i = 1 To ActiveDocument.Sections.Count
With ActiveDocument.Sections(i)
' Remove footer
'.Footers(wdHeaderFooterPrimary).Range.Text = ""
'.Footers(wdHeaderFooterPrimary).PageNumbers.Add (wdAlignPageNumberCenter)
'.Footers(wdHeaderFooterPrimary).Range.InsertBefore "Hit Overview / Page "
.Footers(wdHeaderFooterPrimary).Range.Select
With Selection
If ActiveDocument.Bookmarks.Exists("HitOverviewMac") = True Then
.Paragraphs(1).Alignment = wdAlignParagraphCenter
.TypeText Text:="Page "
.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"PAGE ", PreserveFormatting:=True
.TypeText Text:=" of "
.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"NUMPAGES ", PreserveFormatting:=True
.EndKey Unit:=wdLine
.TypeText Text:=" ~ "
ActiveDocument.Hyperlinks.Add Anchor:=.Range, Address:="", _
SubAddress:="HitOverview", ScreenTip:="", TextToDisplay:="Hit Overview"
Else
MsgBox "Bookmark does not exists"
End If
End With
End With
Next
End Sub

Ok, Its wasn't the problem with Macro(except below), its the problem with couple of Documents I was testing with.
few mistakes that I missed - SubAddress:="BOOKMARK_NAME" AND Anchor:=Selection.Range.
So the problem occurs if any Doc already has some text in footers. and so that now I am removing footer first.
Here is the Code for everyone's reference-
Sub InsertFootnote()
Const wdAlignPageNumberCenter = 1
Dim varNumberPages As Variant
varNumberPages = ActiveDocument.Content.Information(wdActiveEndAdjustedPageNumber)
If ActiveDocument.Bookmarks.Exists("HitOverviewMac") = True Then
ActiveDocument.Bookmarks("HitOverviewMac").Delete
End If
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:="HitOverviewMac"
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
Dim mHlink As Hyperlink
Dim i As Long
For i = 1 To ActiveDocument.Sections.Count
With ActiveDocument.Sections(i)
.Footers(wdHeaderFooterPrimary).Range.Text = ""
.Footers(wdHeaderFooterPrimary).PageNumbers.Add (wdAlignPageNumberCenter)
.Footers(wdHeaderFooterPrimary).Range.Select
With Selection
If ActiveDocument.Bookmarks.Exists("HitOverviewMac") = True Then
.Paragraphs.Alignment = wdAlignParagraphCenter
.TypeText Text:="Page "
.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"PAGE ", PreserveFormatting:=True
.TypeText Text:=" of "
.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"NUMPAGES ", PreserveFormatting:=True
.EndKey Unit:=wdLine
.TypeText Text:=" / "
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:="", _
SubAddress:="HitOverviewMac", ScreenTip:="", TextToDisplay:="Hit Overview"
Else
MsgBox "Bookmark does not exists"
End If
End With
End With
Next
End Sub

Related

How do I extract the line my selection.find found? It will only return to me the first character

In the following code I am trying to insert a picuture into my word document based on the text I found while searchiung. The problem is it will only return to me the firsat character od the text. How do I get all of the text? How do I get the actual line it was found in? The text I am looking for is directly after the text found. IE: "Insert screen shot here of Boxshot" So I am trying to load a file called Boxshot. NOT working. Help.
Sub NewPic()
'
' NewPic Macro
'
Dim screenshot, Dirname, selfound As String
Dim Dn As Long
'
With Selection.Find
.Text = "Insert screen shot here of "
'.Replacement.Text = ""
.Forward = True
End With
Selection.Find.Execute
'
'Insert picture and find next match
'
While Selection.Find.Found
Selection.TypeParagraph
Selection.TypeParagraph
Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Selection.Select
selfound = Selection.Characters.First
MsgBox ("Text=" & selfound)
'
'Is picture there?
'
Dirname = ActiveDocument.Name
Dn = InStr(Dirname, "User")
Dirname = Left(Dirname, Dn)
screenshot = "C:\Users\User 1\Desktop\VB Upload files\CD's\" & Dirname & "\" &
Selection.Text & ".jpg"
MsgBox ("Screenshot= " & screenshot & ", Sellectedtext=" & Selection.Text)
'
If Dir(screenshot) <> "" Then
Else
screenshot = "C:\Users\User 1\Desktop\Mylogo.jpg"
End If
'
Selection.InlineShapes.AddPicture FileName:= _
screenshot, LinkToFile:=False, SaveWithDocument _
:=True
'"C:\Users\User 1\Desktop\Mylogo.jpg", LinkToFile:=False, SaveWithDocument _
':=True
Selection.TypeParagraph
Selection.TypeParagraph
Selection.MoveDown Unit:=wdParagraph, Count:=1
Selection.TypeParagraph
Selection.Find.Execute
Wend
'
End Sub
Your use of Selection makes your code unnecessarily complex and slow. The following macro will insert the relevant pictures wherever "Insert screen shot here of " is followed by the pic name (no error-checking for valid names & files). If you don't want to retain the pic names below the pics, simply un-comment the commented-out line.
Sub NewPics()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "Insert screen shot here of "
.Replacement.Text = ""
.Forward = True
.Format = False
.Wrap = wdFindContinue
End With
Do While .Find.Execute
.Text = vbCr
.Collapse wdCollapseEnd
.End = .Paragraphs.Last.Range.End - 1
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.InlineShapes.AddPicture FileName:=ActiveDocument.Path & "\" & .Text & ".jpg", LinkToFile:=False, SaveWithDocument:=True
'.Start = .Start + 1: .Delete
Loop
End With
Application.ScreenUpdating = True
End Sub

MS Word - link to header of current section / relative referencing

I'm working on a largeish document with multi-level headings, for a long set of test procedures. At the end of each procedure, there is a sign-off box. I want to add the section number and name to each sign-off box.
I researched (here, of course!) and wrote a macro to insert a reference to the heading of the current section, it appears to work fine:
Sub InsertCrossRefToSectionHeading()
Dim RefList As Variant
Dim LookUp As String
Dim Ref As String
Dim i As Integer
LookUp = ActiveDocument.Bookmarks("\HeadingLevel").Range.Paragraphs(1).Range.ListFormat.ListString
With ActiveDocument
RefList = .GetCrossReferenceItems(wdRefTypeHeading)
For i = UBound(RefList) To 1 Step -1
Ref = Trim(RefList(i))
If Left(Ref, Len(LookUp)) = LookUp Then Exit For
Next i
If i Then
Selection.InsertCrossReference ReferenceType:=wdRefTypeHeading, _
ReferenceKind:=wdNumberFullContext, _
ReferenceItem:=CStr(i), _
InsertAsHyperlink:=True, _
IncludePosition:=False, _
SeparateNumbers:=False, _
SeparatorString:=" "
Selection.TypeText Text:=vbTab
Selection.InsertCrossReference ReferenceType:=wdRefTypeHeading, _
ReferenceKind:=wdContentText, _
ReferenceItem:=CStr(i), _
InsertAsHyperlink:=True, _
IncludePosition:=False, _
SeparateNumbers:=False, _
SeparatorString:=" "
'Copy the formatting from the previous cell in the template table and apply to refrence text.
Selection.MoveLeft Unit:=wdCell
Selection.CopyFormat
Selection.MoveRight Unit:=wdCell
Selection.PasteFormat
Else
MsgBox "A cross reference to """ & LookUp & """ couldn't be set" & vbCr & _
"because a paragraph with that number couldn't" & vbCr & _
"be found in the document.", _
vbInformation, "Invalid cross reference"
End If
End With
End Sub
However, it is a hard-linked reference to the heading that was the heading for this section at the time of running the macro. If I add a section, all references in the sign-off boxes after that section are pointing at the previous section, and it defeats the purpose of it.
Yes, my macro will make it much quicker to fix, but there will be a lot of rework every time I add a section to this evolving document. And yes, I could possibly even programmatically search the document for tables with "Test Record" in the top row, then delete Row 2 Cell 2 and insert the reference... but that's a lot of extra programming!... I've done a ton of VBA in Excel, but am new to it in Word. I guess I could leave the references until the very end... of this edit - but then I'll have to do it all again if the doc evolves in the future (which is very likely).
Is there any way to reference the heading of the current section?
Thanks for your help!
Thanks to #CharlesKenyon, here's the solution (much simpler than my first attempt too!).
Sub InsertCrossRefToSectionHeading()
' Adds ref to the heading of the current section.
'https://stackoverflow.com/questions/67200486/ms-word-link-to-header-of-current-section-relative-referencing
'http://www.addbalance.com/usersguide/fields.htm#STYLEREF
CurrentHeadingLevel = ActiveDocument.Bookmarks("\HeadingLevel").Range.Paragraphs(1).Range.ListFormat.ListLevelNumber
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"STYLEREF ""Heading " & CurrentHeadingLevel & """ \w ", PreserveFormatting:=True
Selection.TypeText Text:=" "
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"STYLEREF ""Heading " & CurrentHeadingLevel & """ ", PreserveFormatting:=True
'Copy the formatting from the previous cell in the template table and apply to refrence text.
Selection.MoveLeft Unit:=wdCell
Selection.CopyFormat
Selection.MoveRight Unit:=wdCell
Selection.PasteFormat
End Sub

Problem Formatting Page XX of XX in Word Footer Using VBA

I'm building my footers via code. I'm having an issue properly formatting the page counts in my Word footer when adding the fields via VBA. When the code runs the formatting always ends up as XXof XX (1of 20) instead of XX of XX (1 of 20). I have tried the following but the numbers always show the page number without a space before the word "of".
With rng
.Text = "NUMPAGES "
Set oFooterRng1 = rng.Words(1)
.Fields.Add Range:=oFooterRng1, Type:=wdFieldEmpty, Text:="NUMPAGES \* Arabic ", PreserveFormatting:=True
End With
rng.Collapse wdCollapseStart
rng.Text = " of "
rng.Collapse wdCollapseStart
With rng
.Text = "PAGE "
Set oFooterRng1 = rng.Words(1)
.Fields.Add Range:=oFooterRng1, Type:=wdFieldEmpty, Text:="PAGE \* Arabic ", PreserveFormatting:=True
End With
or this
With rng
.Text = "PAGE of NUMPAGES "
Set oFooterRng1 = rng.Words(1)
Set oFooterRng2 = rng.Words(3)
.Fields.Add Range:=oFooterRng1, Type:=wdFieldEmpty, Text:="PAGE \* Arabic ", PreserveFormatting:=True
.Fields.Add Range:=oFooterRng2, Type:=wdFieldEmpty, Text:="NUMPAGES \* Arabic ", PreserveFormatting:=True
End With
Try something based on:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary).Range
.InsertAfter Text:="Page "
.Fields.Add Range:=.Characters.Last, Type:=wdFieldEmpty, Text:="PAGE", PreserveFormatting:=False
.InsertAfter Text:=" of "
.Fields.Add Range:=.Characters.Last, Type:=wdFieldEmpty, Text:="NUMPAGES", PreserveFormatting:=False
End With
Application.ScreenUpdating = True
End Sub
And, to do it in reverse as you're trying to achieve:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary).Range
.Fields.Add Range:=.Characters.Last, Type:=wdFieldEmpty, Text:="NUMPAGES", PreserveFormatting:=False
.Collapse wdCollapseStart
.Text = " of "
.Collapse wdCollapseStart
.Fields.Add Range:=.Duplicate, Type:=wdFieldEmpty, Text:="PAGE", PreserveFormatting:=False
.Collapse wdCollapseStart
.Text = "Page "
End With
Application.ScreenUpdating = True
End Sub

Macro (VBA) crashing Microsoft word (Find and replace)

I using a VBA code to batch find and replace highlighted text. The macro finds and replaces the words in the document. It works well with a few number of highlighted text on a small document (1-2 pages). However, when I use this macro on a large documents which has over a 100 pages, Microsoft word crashed and becomes unresponsive so I have to forced to quit.
The code is to help make it easy to redact information. I am replacing the highlight text which occur also in tables with XXXXX and highlighted black.
Does anyone have any tips to make the code more efficient?
Here is the code
Sub FindandReplaceHighlight()
Dim strFindColor As String
Dim strReplaceColor As String
Dim strText As String
Dim objDoc As Document
Dim objRange As Range
Application.ScreenUpdating = False
Set objDoc = ActiveDocument
strFindColor = InputBox("Specify a color (enter the value):", "Specify Highlight Color")
strReplaceColor = InputBox("Specify a new color (enter the value):", "New Highlight Color")
strText = InputBox("Specify a new text (enter the value):", "New Text")
With Selection
.HomeKey Unit:=wdStory
With Selection.Find
.Highlight = True
Do While .Execute
If Selection.Range.HighlightColorIndex = strFindColor Then
Set objRange = Selection.Range
objRange.HighlightColorIndex = strReplaceColor
objRange.Text = strText
objRange.Font.ColorIndex = wdBlack
Selection.Collapse wdCollapseEnd
End If
Loop
End With
End With
Application.ScreenUpdating = True
End Sub
Try:
Sub FindandReplaceHighlight()
Application.ScreenUpdating = False
Dim ClrFnd As Long, ClrRep As Long, strTxt As String
Const StrColors As String = vbCr & _
" 1 Black" & vbCr & _
" 2 Blue" & vbCr & _
" 3 Turquoise" & vbCr & _
" 4 Bright Green" & vbCr & _
" 5 Pink" & vbCr & _
" 6 Red" & vbCr & _
" 7 Yellow" & vbCr & _
" 8 White" & vbCr & _
" 9 Dark Blue" & vbCr & _
"10 Teal" & vbCr & _
"11 Green" & vbCr & _
"12 Violet" & vbCr & _
"13 Dark Red" & vbCr & _
"14 Dark Yellow" & vbCr & _
"15 Gray 50" & vbCr & _
"16 Gray 25%"
ClrFnd = InputBox("Specify the old color (enter the value):" & StrColors, "Specify Highlight Color")
ClrRep = InputBox("Specify the new color (enter the value):" & StrColors, "New Highlight Color")
strTxt = InputBox("Specify the new text (enter the value):", "New Text")
With ActiveDocument
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Highlight = True
.Forward = True
.Wrap = wdFindStop
End With
Do While .Find.Execute
If .HighlightColorIndex = ClrFnd Then
.HighlightColorIndex = ClrRep
.Text = strTxt
.Font.ColorIndex = wdBlack
.Collapse wdCollapseEnd
End If
Loop
End With
End With
Application.ScreenUpdating = True
End Sub

Add header and footer macro

I need to make a difficult makro.
When the makro has been activated (will happen via a button), it has to add a header and a footer to the document.
Also page1/frontpage needs a different header and footer than all the other potential pages.
So far, I have accomplished making page1/frontpage to work - somewhat.
I did this by recording a makro, where I'd enable headers and footers, write the needed data and then stop recording. Afterwards I edited the coding so it would fit a little better. Mostly it was junk-code cleanup.
It doesn't work though, if I use several pages.
How can I accomplish this setup?
I can provide you my current code, if anyone is interested:
Sub PDFtest2()
'
' PDFtest2 Macro
'
'
Dim FileName As String
Dim minPDFSti As String
Dim aryFolders
Dim i As Long
Dim version As String
Dim sFolder As String
'Skaf dokument titel
FileName = ActiveDocument.Name 'e.g document1.doc
aryFolders = Split(FileName, ".") 'split ved .doc da vi skal bruge pdf extension
FileName = aryFolders(LBound(aryFolders)) 'document1
'Lav en document-1 hvis document allerede eksistere. Putter også .pdf på som extension
If Dir(minPDFSti + FileName + ".pdf") <> "" Then
aryFolders = Split(FileName, "-")
version = aryFolders(UBound(aryFolders))
If version <> "" Then
FileName = FileName + "-" + version + "-1.pdf"
Else
FileName = FileName + "-1.pdf"
End If
Else
FileName = FileName + ".pdf"
End If
'Vores PDF sti
minPDFSti = "c:\PDF\"
If Dir(minPDFSti, vbDirectory) = "" Then
'If MsgBox("PDF Mappen eksistere ikke, lav en?", _
'vbYesNo, "PDF Mappe") = vbYes Then
aryFolders = Split(minPDFSti, "\")
sFolder = aryFolders(LBound(aryFolders))
For i = LBound(aryFolders) + 1 To UBound(aryFolders)
sFolder = sFolder & "\" & aryFolders(i)
If Dir(sFolder, vbDirectory) = "" Then MkDir sFolder
Next i
'End If
End If
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Selection.TypeText Text:="Advokatfirmaet"
Selection.TypeParagraph
Selection.TypeText Text:="Beck & Partnere"
Selection.MoveLeft Unit:=wdCharacter, Count:=15, Extend:=wdExtend
Selection.Font.Size = 12
Selection.Font.Size = 13
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.MoveLeft Unit:=wdCharacter, Count:=16, Extend:=wdExtend
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Font.Bold = wdToggle
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.MoveLeft Unit:=wdCharacter, Count:=15, Extend:=wdExtend
Selection.Font.Bold = wdToggle
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.TypeText Text:="Advokataktieselskab"
Selection.ParagraphFormat.TabStops.Add Position:=CentimetersToPoints(4.5), _
Alignment:=wdAlignTabLeft, Leader:=wdTabLeaderSpaces
Selection.TypeText Text:=vbTab & "Damhaven 5"
Selection.ParagraphFormat.TabStops(CentimetersToPoints(7.96)).Position = _
CentimetersToPoints(7.96)
Selection.ParagraphFormat.TabStops.Add Position:=CentimetersToPoints(8.25) _
, Alignment:=wdAlignTabLeft, Leader:=wdTabLeaderSpaces
Selection.ParagraphFormat.TabStops(CentimetersToPoints(7.96)).Position = _
CentimetersToPoints(8.25)
Selection.TypeText Text:=vbTab & "Giro 193 5100"
Selection.ParagraphFormat.TabStops.Add Position:=CentimetersToPoints(12.25 _
), Alignment:=wdAlignTabLeft, Leader:=wdTabLeaderSpaces
Selection.TypeText Text:=vbTab & "Tel." & vbTab & "+45 75 72 41 00"
Selection.TypeParagraph
Selection.TypeText Text:="CVR 25 79 71 24" & vbTab & "DK-7100 Vejle" & _
vbTab
Selection.ParagraphFormat.TabStops(CentimetersToPoints(8.25)).Position = _
CentimetersToPoints(9)
Selection.ParagraphFormat.TabStops.Add Position:=CentimetersToPoints(8.25) _
, Alignment:=wdAlignTabLeft, Leader:=wdTabLeaderSpaces
Selection.TypeText Text:="www.becklaw.dk" & vbTab & "Fax" & vbTab & _
"+45 75 72 41 00"
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveLeft Unit:=wdCharacter, Count:=26
Selection.ParagraphFormat.TabStops.Add Position:=CentimetersToPoints(8.25) _
, Alignment:=wdAlignTabLeft, Leader:=wdTabLeaderSpaces
Selection.ParagraphFormat.TabStops(CentimetersToPoints(8.25)).Position = _
CentimetersToPoints(9)
Selection.ParagraphFormat.TabStops(CentimetersToPoints(9)).Position = _
CentimetersToPoints(8.25)
ChangeFileOpenDirectory minPDFSti 'Sikre dig at stien eksistere
ActiveDocument.ExportAsFixedFormat OutputFileName:= _
minPDFSti + FileName, ExportFormat:= _
wdExportFormatPDF, OpenAfterExport:=True, OptimizeFor:= _
wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, To:=1, _
Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
BitmapMissingFonts:=True, UseISO19005_1:=False
Selection.WholeStory
Selection.TypeBackspace
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.WholeStory
Selection.TypeBackspace
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub
The code also saves the dokument as a PDF. But that doesn't matter.
EDIT: Actually this accomplishes an odd result!
Let us say that I have a page1, 2 & 3 filled with text.
I press the button that activates the macro.
Page 1 recieves no header nor footer, but page 2 & 3 recieves the header and footer coded above.
Try this:
Sub HeaderFooterObject()
Dim MyText As String
MyHeaderText = "Header text"
MyFooterText = "Footer text"
MyHeaderTextFirstPage = "First Page"
MyFooterTextFirstPage = "Footer text First Page"
With ActiveDocument.Sections(1)
.PageSetup.DifferentFirstPageHeaderFooter = True
.Headers(wdHeaderFooterPrimary).Range.Text = MyHeaderText
.Footers(wdHeaderFooterPrimary).Range.Text = MyFooterText
.Headers(wdHeaderFooterFirstPage).Range.Text = MyHeaderTextFirstPage
.Footers(wdHeaderFooterFirstPage).Range.Text = MyFooterTextFirstPage
End With
End Sub
This came from here and here.