AppActivate wrd.Name error 5 - trying to Batch replace header image in several MS Word - vba

I need to update a massive number of documents with our new company logo. The task its just to replace the existing header image with a new one. I found an ancient code that should work with older versions of MS Word but it breaks on 365, so I need the help of a kind soul to guide me as I'm illiterate in VBA.
I tried the following code:
Sub ReplaceEntireHdr()
Dim wrd As Word.Application
Set wrd = CreateObject("word.application")
wrd.Visible = True
AppActivate wrd.Name
'Change the directory to YOUR folder's path
FName = Dir("C:\Test\*.doc")
Do While (FName <> "")
With wrd
'Change the directory to YOUR folder's path
.Documents.Open ("C:\Test\" & FName)
If .ActiveWindow.View.SplitSpecial = wdPaneNone Then
.ActiveWindow.ActivePane.View.Type = wdPrintView
Else
.ActiveWindow.View.Type = wdPrintView
End If
.ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
.Selection.WholeStory
.Selection.Paste
.ActiveDocument.Save
.ActiveDocument.Close
End With
FName = Dir
Loop
Set wrd = Nothing
End Sub
It should open all files on a given directory, delete the header and paste the one held on the clipboard. When I try to run it, I get error '5' on line 5 (AppActivate wrd.Name).

The code you in your question is written to be run from outside Word, probably from Excel.
One thing that you need to figure out is which of the three types of header you are replacing. The code below assumes it is the main header. If you need just the first page header replace wdHeaderFooterPrimary with wdHeaderFooterFirstPage. You can tell which header you need by editing the header in the UI and checking the grey label.
The code you have is not well written and can be simplified as below.
Sub ReplaceEntireHdrXL()
Dim wrd As Word.Application
Set wrd = CreateObject("word.application")
wrd.Visible = True
'Change the directory to YOUR folder's path
Dim FName As String
FName = Dir("C:\Test\*.doc")
Dim doc As Document
Do While (FName <> "")
'Change the directory to YOUR folder's path
Set doc = wrd.Documents.Open("C:\Test\" & FName)
With doc
With .Sections(1).Headers(wdHeaderFooterPrimary).Range
.Paste
'if what you have copied includes a paragpraph mark at the end
'you may need to delete the last para in the header
.Paragraphs.Last.Range.Delete
End With
.Save
.Close
End With
FName = Dir
Loop
Set wrd = Nothing
End Sub
You can simplify things further if you run it from Word instead.
Sub ReplaceEntireHdr()
Dim FName As String
'Change the directory to YOUR folder's path
FName = Dir("C:\Test\*.doc")
Dim doc As Document
Do While (FName <> "")
'Change the directory to YOUR folder's path
Set doc = Documents.Open("C:\Test\" & FName)
With doc
With .Sections(1).Headers(wdHeaderFooterPrimary).Range
.Paste
'if what you have copied includes a paragpraph mark at the end
'you may need to delete the last para in the header
.Paragraphs.Last.Range.Delete
End With
.Save
.Close
End With
FName = Dir
Loop
End Sub

Related

Adding existing Header and Footer for multiple word documents

I have around 1000 word documents in one folder which the header and footer needs to be added/changed (header need to added/changed just for the first page).
I found a very helpful VBA script which is work but I tried but can not style and format to my needs, which is shown in the attached pictures
Header Style I need
Footer Style I need
The found working code which i found in stackoverflow:
Sub openAllfilesInALocation()
Dim Doc
Dim i As Integer
Dim docToOpen As FileDialog
Set docToOpen = Application.FileDialog(msoFileDialogFilePicker)
docToOpen.Show
For i = 1 To docToOpen.SelectedItems.Count
'Open each document
Set Doc = Documents.Open(FileName:=docToOpen.SelectedItems(i))
With ActiveDocument.Sections(1)
.Headers(wdHeaderFooterPrimary).Range.Text = "Header goes here"
.Footers(wdHeaderFooterPrimary).Range.Text = "Footer goes here"
End With
Doc.Save
Doc.Close
Next i
End Sub
Thanks in advance for everybody reading and/or helping me with this question, because if I can not work it out, I need to add for around 1000 word docs headers and footers manually...... :( so thanks for helping or just trying!
Before you write code for this you need to break the task down into steps.
Open one of the documents that you need to apply the changes to.
Record a macro whilst you edit the Header style so that it has the correct formatting
Record a macro whilst you edit the Footer style so that it has the correct formatting
Edit the header of the document to include whatever logo and text you require.
Select the content of the header and save as as a Building Block - on the Header & Footer tab click "Header" then "Save Selection to Header Gallery". Ensure that you pay attention to which template you are saving it to as you will need to know this later.
Edit the footer of the document to include whatever text you require.
Select the content of the footer and save as as a Building Block - on the Header & Footer tab click "Footer" then "Save Selection to Footer Gallery". Again ensure that you pay attention to which template you are saving it to.
Now you can write your code. For example:
Sub openAllfilesInALocation()
Dim Doc As Document
Dim i As Integer
Dim BBlockSource As Template
Set BBlockSource = Application.Templates("<Full path to template you stored building blocks in>")
Dim docToOpen As FileDialog
Set docToOpen = Application.FileDialog(msoFileDialogFilePicker)
docToOpen.Show
For i = 1 To docToOpen.SelectedItems.Count
'Open each document
Set Doc = Documents.Open(FileName:=docToOpen.SelectedItems(i))
MacroToModifyHeaderStyle 'name of the macros you recorded in steps 2 & 3
MacroToModifyFooterStyle
With ActiveDocument.Sections(1)
BBlockSource.BuildingBlockEntries("Name of Header Building Block").Insert .Headers(wdHeaderFooterFirstPage).Range
BBlockSource.BuildingBlockEntries("Name of Footer Building Block").Insert .Footers(wdHeaderFooterFirstPage).Range
'you may need the following if an extra paragraph is created when adding the building block
'.Headers(wdHeaderFooterFirstPage).Range.Paragraphs.Last.Range.Delete
'.Footers(wdHeaderFooterFirstPage).Range.Paragraphs.Last.Range.Delete
End With
Doc.Save
Doc.Close
Next i
End Sub
Obviously you test your code on a copy of some of the files before attempting to run it on all of them.
Simply add the following macro to a document containing your new header & footer, then run the macro, which includes a folder browser so you can select the folder to process.
Sub UpdateDocumentHeaders()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String
Dim wdDocTgt As Document, wdDocSrc As Document
Dim Sctn As Section, HdFt As HeaderFooter
strFolder = GetFolder
If strFolder = "" Then Exit Sub
Set wdDocSrc = ActiveDocument
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
If strFolder & "\" & strFile <> wdDocSrc.FullName Then
Set wdDocTgt = Documents.Open(FileName:=strFolder & "\" & strFile, _
AddToRecentFiles:=False, Visible:=False)
With wdDocTgt
For Each Sctn In .Sections
'For Headers
For Each HdFt In Sctn.Headers
With HdFt
If .Exists Then
If .LinkToPrevious = False Then
.Range.FormattedText = _
wdDocSrc.Sections.First.Headers(wdHeaderFooterPrimary).Range.FormattedText
End If
End If
End With
Next
'For footers
For Each HdFt In Sctn.Footers
With HdFt
If .Exists Then
If .LinkToPrevious = False Then
.Range.FormattedText = _
wdDocSrc.Sections.First.Footers(wdHeaderFooterPrimary).Range.FormattedText
End If
End If
End With
Next
Next
.Close SaveChanges:=True
End With
End If
strFile = Dir()
Wend
Set wdDocSrc = Nothing: Set wdDocTgt = Nothing
Application.ScreenUpdating = True
End Sub
Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function
As coded, the macro assumes the document you're running the macro from has only one Section, with up to three populated headers (as allowed by Word), and that all headers in the target document are to be updated to match the source document's primary header & footer. If you only want to update headers in the first Section, delete the footer loop and delete 'For Each Sctn In .Sections' and it's 'Next' later in the code and change 'For Each HdFt In Sctn.Headers' to 'For Each HdFt In .Sections(1).Headers'.

VBA Code to change word footer in multiple files based on page number

I have a macro that runs to make a single page doc into a 5 page doc (NCR Duplicates) for all files in a folder.
I am using a set of nested IF fields in my footer, which changes the footer based on page number. The field looks like this
Text here {If{PAGE}="1""Original"{If{PAGE}="2""Copy 1"
{If{PAGE}="3""Copy 2"{If{PAGE}="4""Copy 3"{If{PAGE}="5""Copy 4"}}}}}
Other Text
I am trying to figure out how to add this footer to all the documents in a folder. It doesn't need to use field, if there is a way simply based on page number.
I have bashed my head against the wall, searched like crazy, and now come hat in hand.
The macro to make the duplicate copies is:
Sub Make5CopiesNCR()
vDirectory = BrowseForFolder
vFile = Dir(vDirectory & "\" & "*.*")
Do While vFile <> ""
Documents.Open FileName:=vDirectory & "\" & vFile
MakeCopies
vFile = Dir
Loop
End Sub
End Sub
Private Sub MakeCopies()
Dim i As Integer
Selection.WholeStory
Selection.Copy
For i = 1 To 6
Selection.PasteAndFormat wdFormatOriginalFormatting
Next
With ActiveDocument
.GoTo What:=wdGoToPage, Which:=wdGoToAbsolute, Name:=6 'Page number
.Bookmarks("\Page").Select
With Selection
.Delete
ActiveDocument.Close SaveChanges:=wdSaveChanges, OriginalFormat:=wdWordDocument
End With
End With
End Sub
The problem with using a mailmerge with your field construction is that it gets converted to the result. Try a field coded as:
{={PAGE}-1 \# "'Copy {={PAGE}-1}';;'Original'"}
Now, if you create the required 5 pages in your mailmerge main document, all the outputs will likewise be in multiples of 5 pages, with the correct page numbering.
Even if you use a mailmerge main document with only a single page, the outputs will have the field coding required to produce the correct numbering for however many more pages you want to add to the outputs.
As for replicating this in your existing files, simply create a document with the required footer content, then use a macro like:
Sub ReplicateFooter()
Application.ScreenUpdating = False
Dim DocSrc As Document, DocTgt As Document, Rng As Range
Dim StrPth As String, StrNm As String, StrSrc As String
Set DocSrc = ActiveDocument
Set Rng = DocSrc.Sections.First.Footers(wdHeaderFooterPrimary).Range
StrPth = DocSrc.Path & "\": StrSrc = DocSrc.FullName
StrNm = Dir(StrPth & "*.doc", vbNormal)
While StrNm <> ""
If StrPth & StrNm <> StrSrc Then
Set DocTgt = Documents.Open(FileName:=StrPth & StrNm, AddToRecentFiles:=False, Visible:=False)
With DocTgt
With .Sections.First.Footers(wdHeaderFooterPrimary).Range
.FormattedText = Rng.FormattedText
.Characters.Last.Text = vbNullString
End With
.Close True
End With
End If
StrNm = Dir()
Wend
Set Rng = Nothing: Set DocTgt = Nothing: Set DocSrc = Nothing
Application.ScreenUpdating = True
End Sub

Text Replacement in MS Word

In my MS-Word template, my client sends template with an error in the header section, as below,
VERMONT, ROBIN S. Date: 10/21/2017
File No: 312335 DOB: 05/02/1967Claim#: RE155B53452
DOI: 06/21/2017
The error being the ‘Claim#’ coming up right next to the DOB value, while it should come on the next line, as below:
VERMONT, ROBIN S. Date: 10/21/2017
File No: 312335 DOB: 05/02/1967
Claim#: RE155B53452 DOI: 06/21/2017
Also, this error comes up occasionally in some files and not all, so to solve it, I created a word macro, as below:
Sub ShiftClaimNumber2NextLine()
Dim rngStory As Word.Range
Dim lngJunk As Long
'Fix the skipped blank Header/Footer problem as provided by Peter Hewett
lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType
'Iterate through all story types in the current document
For Each rngStory In ActiveDocument.StoryRanges
'Iterate through all linked stories
Do
With rngStory.Find
.text = "Claim#:"
.Replacement.text = "^pClaim#:"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
'Get next linked story (if any)
Set rngStory = rngStory.NextStoryRange
Loop Until rngStory Is Nothing
Next
End Sub
And I run the above macro through a Group Macro, as below:
Sub ProcessAllDocumentsInFolder()
Dim file
Dim path As String
' Path to folder
path = "D:\Test\"
file = Dir(path & "*.doc")
Do While file <> ""
Documents.Open FileName:=path & file
' Call the macro to run on each file in the folder
Call ShiftClaimNumber2NextLine
' Saves the file
ActiveDocument.Save
ActiveDocument.Close
' set file to next in Dir
file = Dir()
Loop
End Sub
When I run the macro ProcessAllDocumentsInFolder(), for all files with such an error, it shifts the ‘Claim#’ to the next line.
However, the problem is, it also does so for files that do not have such a problem, thereby adding one enter line below the DOB, as below (as depicted by the yellow line):
What changes should I make to my macro ShiftClaimNumber2NextLine() , so that it does not make any change to files which DO NOT HAVE the ‘Claim#’ problem ?
This is a situation best suited to regular expressions see below link for similar issue, refer vba solution
https://superuser.com/questions/846646/is-there-a-way-to-search-for-a-pattern-in-a-ms-word-document
Sub RegexReplace()
Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
On Error Resume Next
RegEx.Global = True
RegEx.Pattern = "[0-9]Claim#:"
ActiveDocument.Range = _
RegEx.Replace(ActiveDocument.Range, "\rClaim#:")
End Sub

Assistance needed in automating the process of populating a word template from Excel

I'm a complete newbie to VBA and would really appreciate some help automating a process, if anyone would be so kind. :)
I am trying to populate a Word template from an excel spreadsheet I have created
I have found some code which emables me to open my Word template, but that's as far as I'm capable of going :( lol
Private Sub PrintHDR_Click()
Dim objWord As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open "C:\Users\Duncan\Desktop\HDR.dotx"
End Sub
The next step I wish to achieve is to copy and paste data from certain cells into my Word document.
I have set up the bookmarks in Word and have named the cells I wish to copy.
Some cells contain text, other cells contain formulas / sums which produce a numerical answer. In the cells that contain formulas or sums, it is the answer which I want copied to Word.
Any help would be much appreciated.
Thanks in advance :)
Duncan
I have code that does something like this. In Word, instead of using bookmarks for the fields to replace, I just use a special marker (like <<NAME>>).
You may have to adapt. I use a ListObject (the new Excel "Tables"), you can change that if you use a simple Range.
Create a "Template.docx" document, make it read-only, and place your replaceable fields there (<<NAME>>, etc.). A simple docx will do, it doesn't have to be a real template (dotx).
Public Sub WriteToTemplate()
Const colNum = 1
Const colName = 2
Const colField2 = 3
Const cBasePath = "c:\SomeDir"
Dim wordDoc As Object, sFile As String, Name As String
Dim lo As ListObject, theRow As ListRow
Dim item As tItem
Set lo = ActiveCell.ListObject
Set theRow = ActiveCell.ListObject.ListRows(ActiveCell.Row - lo.Range.Row)
With theRow.Range
'I use one of the columns for the filename:
Debug.Print "writing " & theRow.Range.Cells(1, colName).text
'A filename cannot contain any of the following characters: \ / : * ? " < > |
Name = Replace(.Cells(1, colName), "?", "")
Name = Replace(Name, "*", "")
Name = Replace(Name, "/", "-")
Name = Replace(Name, ":", ";")
Name = Replace(Name, """", "'")
sFile = (cBasePath & "\" & Name) & ".docx"
Debug.Print sFile
Set wordApp = CreateObject("word.Application")
If Dir(sFile) <> "" Then 'file already exists
Set wordDoc = wordApp.Documents.Open(sFile)
wordApp.Visible = True
wordApp.Activate
Else 'new file
Set wordDoc = wordApp.Documents.Open(cBasePath & "\" & "Template.docx")
wordApp.Selection.Find.Execute Forward:=(wordApp.Selection.Start = 0), FindText:="««NUM»»", ReplaceWith:=.Cells(1, colNum)
wordApp.Selection.Collapse direction:=1 'wdCollapseEnd
wordApp.Selection.Find.Execute FindText:="««NAME»»", ReplaceWith:=.Cells(1, colName)
wordApp.Selection.Collapse direction:=1 'wdCollapseEnd
wordApp.Selection.Find.Execute FindText:="««FIELD2»»", ReplaceWith:=.Cells(1, colField2)
wordDoc.ListParagraphs.item(1).Range.Select
wordApp.Selection.Collapse direction:=1 'wdCollapseEnd
wordApp.Visible = True
wordApp.Activate
On Error Resume Next
'if this fails (missing directory, for example), file will be unsaved, and Word will ask for name.
wordDoc.SaveAs sFile 'Filename:=(cBasePath & "\" & .Cells(1, colName))
On Error GoTo 0
End If
End With
End Sub
This basically replicates the Mail Merge function in code, to give you more control.

To Add Header and Footer for many word documents?

I have around 100 documents for which the header and footer need to be changed.
Is there a possibility that i can do it just by writing a vba code or Macro in a word file?
Is it possible to give a specific folder in a macro which ll add the header and footer for all the documents in that footer?
the below code gives me
error-5111
Private Sub Submit_Click()
Call openAllfilesInALocation
End Sub
Sub openAllfilesInALocation()
Dim i As Integer
With Application.FileSearch
.NewSearch
.LookIn = "C:\MyFolder\MySubFolder"
.SearchSubFolders = False
.FileName = "*.xls"
.Execute
For i = 1 To .FoundFiles.Count
'Open each workbook
Set Doc = Documents.Open(FileName:=.FoundFiles(i))
'Perform the operation on the open workbook
'wb.Worksheets("sheet1").Range("A1") = Date
'Save and close the workbook
With ActiveDocument.Sections(1)
.Headers(wdHeaderFooterPrimary).Range.Text = "Header goes here"
.Footers(wdHeaderFooterPrimary).Range.Text = "Footer goes here"
End With
Doc.Save
Doc.Close
'On to the next workbook
Next i
End With
End Sub
In the code you provided you have tried to use old .FileSearch property. It used to work until MS Office 2003 but not now. Here goes code improved for you. It will open a standard file window where you can pick one or few files to process.
Sub openAllfilesInALocation()
Dim Doc
Dim i As Integer
Dim docToOpen As FileDialog
Set docToOpen = Application.FileDialog(msoFileDialogFilePicker)
docToOpen.Show
For i = 1 To docToOpen.SelectedItems.Count
'Open each document
Set Doc = Documents.Open(FileName:=docToOpen.SelectedItems(i))
With ActiveDocument.Sections(1)
.Headers(wdHeaderFooterPrimary).Range.Text = "Header goes here"
.Footers(wdHeaderFooterPrimary).Range.Text = "Footer goes here"
End With
Doc.Save
Doc.Close
Next i
End Sub