To Add Header and Footer for many word documents? - vba

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

Related

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

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

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'.

Append Word docx files while keeping their format in VBA

I am creating a Word Macro that receives two arguments: a list of docx documents and the name of the new file. The goal is that the Macro inserts one document after the other, preserving their respective format, and saves as a new docx document.
Sub Merger(path As String, args () As Variant)
Dim vArg As Variant
Active Document.Select
Selection.ClearFormatting
For Each vArg In args
ActiveDocument.Content.Words.Last.Select
Selection.InsertFile:= _ vArg _,Range:="", _ConfirmConversions:= False, Link:=False, Attachment:= False )
Selection.InsertBreak Type:=wdPageBreak
Next vArg
ActiveDocument.SaveAs2 File Name=path
ActiveDocument.Close
Application.Quit
Note that I call the Macro from an empty docx file.
The problem is that neither the header nor the format of the orginal files are preserved in the new docx document.
The Word format is not modular. Instead, consider creating a Master Document, then filling it with subdocuments. Here's code to create a master document from a folder full of subdocuments:
Sub AssembleMasterDoc()
Dim SubDocFile$, FolderPath$, Template$
Dim Counter&
Dim oFolder As FileDialog
Dim oBookmark As Bookmark
Dim oTOC As TableOfContents
'Create a dynamic array variable, and then declare its initial size
Dim DirectoryListArray() As String
ReDim DirectoryListArray(1000)
Template$ = ActiveDocument.AttachedTemplate.Path & Application.PathSeparator & ActiveDocument.AttachedTemplate.Name
'Loop through all the files in the directory by using Dir$ function
Set oFolder = Application.FileDialog(msoFileDialogFolderPicker)
With oFolder
.AllowMultiSelect = False
If .Show <> 0 Then
FolderPath$ = .SelectedItems(1)
Else
GoTo EndSub
End If
End With
Application.ScreenUpdating = False
SubDocFile$ = Dir$(FolderPath$ & Application.PathSeparator & "*.*")
Do While SubDocFile$ <> ""
DirectoryListArray(Counter) = SubDocFile$
SubDocFile$ = Dir$
Counter& = Counter& + 1
Loop
'Reset the size of the array without losing its values by using Redim Preserve
ReDim Preserve DirectoryListArray(Counter& - 1)
WordBasic.SortArray DirectoryListArray()
ActiveWindow.ActivePane.View.Type = wdOutlineView
ActiveWindow.View = wdMasterView
Selection.EndKey Unit:=wdStory
For x = 0 To (Counter& - 1)
If IsNumeric(Left(DirectoryListArray(x), 1)) Then
FullName$ = FolderPath$ & Application.PathSeparator & DirectoryListArray(x)
Documents.Open FileName:=FullName$, ConfirmConversions:=False
With Documents(FullName$)
.AttachedTemplate = Template$
For Each oBookmark In Documents(FullName$).Bookmarks
oBookmark.Delete
Next oBookmark
.Close SaveChanges:=True
End With
Selection.Range.Subdocuments.AddFromFile Name:=FullName$, ConfirmConversions:=False
End If
Next x
For Each oTOC In ActiveDocument.TablesOfContents
oTOC.Update
Next oTOC
ActiveWindow.ActivePane.View.Type = wdPrintView
Application.ScreenUpdating = True
EndSub:
End Sub
This code is from a previous project, so you may not need all of it, like the update of multiple TOCs.
Don't attempt to maintain and edit Master Documents. The format is prone to corruption. Instead, assemble a master document for printing (or other use), then discard it.

How can I find & replace text across multiple files inside text boxes?

I would like to change text that repeats in .doc and .docx files.
I have this macro running at the moment:
Option Explicit
Public Sub BatchReplaceAll()
Dim FirstLoop As Boolean
Dim myFile As String
Dim PathToUse As String
Dim myDoc As Document
Dim Response As Long
PathToUse = "C:\Files\"
'Error handler to handle error generated whenever
'the FindReplace dialog is closed
On Error Resume Next
'Close all open documents before beginning
Documents.Close SaveChanges:=wdPromptToSaveChanges
'Boolean expression to test whether first loop
'This is used so that the FindReplace dialog will'only be displayed for the first document
FirstLoop = True
'Set the directory and type of file to batch process
myFile = Dir$(PathToUse & "*.docx")
While myFile <> ""
'Open document
Set myDoc = Documents.Open(PathToUse & myFile)
If FirstLoop Then
'Display dialog on first loop only
Dialogs(wdDialogEditReplace).Show
FirstLoop = False
Response = MsgBox("Do you want to process " & _
"the rest of the files in this folder", vbYesNo)
If Response = vbNo Then Exit Sub
Else
'On subsequent loops (files), a ReplaceAll is
'executed with the original settings and without
'displaying the dialog box again
With Dialogs(wdDialogEditReplace)
.ReplaceAll = 1
.Execute
End With
End If
'Close the modified document after saving changes
myDoc.Close SaveChanges:=wdSaveChanges
'Next file in folder
myFile = Dir$()
Wend
End Sub
It does work if replacing simple text.
How can I search and replace inside Text Boxes?
EDIT 1:
I changed this:
With Dialogs(wdDialogEditReplace)
.ReplaceAll = 1
.Execute
End With
To this:
With Dialogs(wdDialogEditReplace)
For Each myStoryRange In ActiveDocument.StoryRanges
With myStoryRange.Find
.Text = "ORIGINAL_TEXT"
.Replacement.Text = "MODIFIED_TEXT"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Do While Not (myStoryRange.NextStoryRange Is Nothing)
Set myStoryRange = myStoryRange.NextStoryRange
With myStoryRange.Find
.Text = "ORIGINAL_TEXT"
.Replacement.Text = "MODIFIED_TEXT"
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Loop
Next myStoryRange
End With
The problems with this new code is that sometimes it skips text boxes and it is slow.
In VBA, Word "Text Boxes" are known as a TextFrame Object. This may be able to point you in the right direction:
For Each s In ActiveDocument.Shapes
With s.TextFrame
If .HasText Then MsgBox .TextRange.Text
End With
Next
I will update my answer when I get more information on implementing it into your example.

Open Excel from Word using FileDialog

What I want to do is:
Press a button in my Microsoft Word doc it will prompt me to select a document in the file explorer.
Select my document the relevant fields in my word doc will be populated.
This will be populated based upon information in the document (the month) and using a Match function it will search for the correct row/column in the selected excel document and return the value.
I am stuck on the FileDialog(msoFileDialogFilePicker) section of my code below.
For the purpose of my document I can not enter the direct file path, the file path needs to be taken from the FileDialog function (or something similar).
I have also tried GetOpenFilename. I am unsure how to do this. My code currently opens FileDialog and lets me select a file, but I can not pass the file path onto my colNum1 line.
The error I get is Run-time error '91'. Object variable or With Block variable not set.
I am open to suggestions and any help is much appreciated.
Sub KPI_Button()
'
' KPI_Button Macro
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Dim strFile As String
Dim Doc As String
Dim Res As Integer
Dim dlgSaveAs As FileDialog
Doc = ThisDocument.Name
Set dlgSaveAs = Application.FileDialog(msoFileDialogFilePicker)
Res = dlgSaveAs.Show
colNum1 = WorksheetFunction.Match("(Month)", ActiveWorkbook.Sheets("Sheet1").Range("A2:I2"), 0)
ThisDocument.hoursworkedMonth.Caption = exWb.Sheets("Sheet1").Cells(3, colNum1)
exWb.Close
Set exWb = Nothing
End Sub
try a dialog that specifies an Excel extension as such:
Sub GetNames()
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel files", "*.xls*", 1
If .Show = True Then
If .SelectedItems.Count > 0 Then
'this is the path you need
MsgBox .SelectedItems(1)
Else
MsgBox "no valid selection"
End If
End If
End With
End Sub