VBA - Change all Word Footer in folder - not more compatible - vba

For years I have used the VBA code below to change the footer in all Word files in a folder (including subfolders).
It works pretty well, but only to the version Word 2003! Now I'm using Word 2010 and if I start the code I get the error:
Run-time error 5111. The command is not available on this platform
Private Sub Image16_Click()
Dim Suchpfad, oPath
Folder = BrowseForFolder("Sélectionnez le dossier où les fichiers doivent être traitées")
If Len(Folder) = 0 Then
MsgBox "Vous n'avez pas sélectionné un dossier!"
Exit Sub
Else
'ChangeFileOpenDirectory Folder
oPath = Folder
'MsgBox oPath
End If
'**** Fußzeilen löschen
Pfad = oPath
With Application.FileSearch
.LookIn = Pfad
.SearchSubFolders = True
.FileType = msoFileTypeWordDocuments
.Execute
For i = 1 To .FoundFiles.Count
strName = .FoundFiles(i)
WordBasic.DisableAutoMacros
Documents.Open FileName:=strName
Dim Abschnitt As Section
For Each Abschnitt In ActiveDocument.Sections
For j = 1 To 3
On Error Resume Next
Abschnitt.Footers(j).Range.Delete
Next j
Next
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
If Selection.HeaderFooter.IsHeader = True Then
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter
Else
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
End If
Selection.WholeStory
Selection.Font.Name = "Verdana"
Selection.Font.Size = 7
Selection.TypeText Text:="First Line of Footer"
Selection.TypeParagraph
Selection.Font.Size = 6
Selection.TypeText Text:="Second Line of Footer"
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
ActiveDocument.Save
ActiveDocument.Close
Next
End With
MsgBox "Operation done in " & Pfad & " !!!"
End Sub
I can't figure out this problem and I hope that somebody has a solution.

First you will need a recursive folder parsing routine. This should work.
Public Sub RecursiveFolderParse(Folder, dictFiles As Object, sExt As String)
Dim SubFolder As Variant
Dim File As Variant
For Each SubFolder In Folder.SubFolders
RecursiveFolderParse SubFolder, dictFiles, sExt
Next
For Each File In Folder.Files
If Right$(File.Name, Len(sExt)) = sExt Then
If Not dictFiles.Exists(File.Path) Then
dictFiles.Add File.Path, 1
End If
End If
Next
End Sub
Then to use this routine, here is your main subroutine where you process each file accordingly:
Public Sub ProcessAllFiles()
Dim sFolder As String
Dim dictFiles As Object
Dim FileSystem As Object
Dim vKeys As Variant
Dim sFilename As Variant
Dim sExt As String
' define your folder and the extension to look for
sFolder = "C:\Test"
sExt = "zip"
Set dictFiles = CreateObject("Scripting.Dictionary")
Set FileSystem = CreateObject("Scripting.FileSystemObject")
RecursiveFolderParse FileSystem.GetFolder(sFolder), dictFiles, sExt
vKeys = dictFiles.Keys
For Each sFilename In vKeys
' process file code goes here
MsgBox sFilename
Next
End Sub

Related

Add Page Number To Footer

I've got a bunch of documents that I need to add page numbering in the footer.
I tried writing a macro to do this but after I run there's still no page numbers (in header or footer)
Sub AddPageNumberToFooter()
Call DeleteExistingFooters
With ActiveDocument
.PageSetup.DifferentFirstPageHeaderFooter = False
.Sections(1).Footers(wdHeaderFooterPrimary).PageNumbers.Add
End With
End Sub
Sub DeleteExistingFooters()
Dim iSectionCnt As Integer
iSectionCnt = ActiveDocument.Sections.Count
If iSectionCnt > 0 Then
ActiveDocument.Sections(iSectionCnt).Footers(wdHeaderFooterPrimary).Range.Delete
End If
End Sub
What am I missing?
The following code will add Page #s to all documents lacking them in every page in the selected folder:
Sub UpdateDocumentFooters()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String
Dim wdDoc As Document, Sctn As Section, HdFt As HeaderFooter
strFolder = GetFolder: If strFolder = "" Then Exit Sub
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
If strFolder & "\" & strFile <> ThisDocument.FullName Then
Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, _
AddToRecentFiles:=False, Visible:=False)
With wdDoc
For Each Sctn In .Sections
For Each HdFt In Sctn.Footers
With HdFt
If .Exists Then
If Sctn.Index = 1 Then
Call AddPgFld(HdFt)
ElseIf .LinkToPrevious = False Then
Call AddPgFld(HdFt)
End If
End If
End With
Next
Next
.Close SaveChanges:=True
End With
End If
strFile = Dir()
Wend
Set wdDoc = Nothing
Application.ScreenUpdating = True
End Sub
Sub AddPgFld(HdFt As HeaderFooter)
Dim Fld As Field, bFld As Boolean
With HdFt
bFld = False
For Each Fld In .Range.Fields
If Fld.Type = wdFieldPage Then
bFld = True: Exit For
End If
Next
If bFld = False Then
With .Range.Paragraphs.Last.Range
If Len(.Text) > 2 Then .InsertAfter vbCr
End With
With .Range.Paragraphs.Last.Range
.Text = "Page "
.Fields.Add Range:=.Characters.Last, Type:=wdFieldEmpty, Text:="PAGE", PreserveFormatting:=False
.ParagraphFormat.Alignment = wdAlignParagraphCenter
End With
End If
End With
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 you are writing that you have a bunch of documents: Could it be that ActiveDocument isn't the correct reference.
This works for me - you can replace ActiveDocument from the test-sub with any other document:
Option Explicit
Sub testPagenumbersForActiveDocument()
dim docToTest as Word.Document
set docToTest = ActiveDocument 'replace ActiveDocument with another doc you have opened
deleteExistingPageNumbers docToTest
addPageNumberToFooter docToTest
End Sub
Sub addPageNumberToFooter(doc As Word.Document)
With doc
.PageSetup.DifferentFirstPageHeaderFooter = False
.Sections(1).Footers(wdHeaderFooterPrimary).PageNumbers.Add
End With
End Sub
Sub deleteExistingPageNumbers(doc As Word.Document)
Dim sec As Section, pn As PageNumber
For Each sec In doc.Sections
For Each pn In sec.Footers(wdHeaderFooterPrimary).PageNumbers
pn.Delete
Next
Next
End Sub
The delete-sub only deletes PageNumbers - this is safer then your version as that will delete the whole footer-text ... which might be not what you want.

Adding new footer to a folder of word documents

I an using a code copied from "Macropod" (sorry if the name is incorrect) to replace every header and footer in a folder of documents with a new header and footer as displayed in the macro document. It is slightly altered to apply to only footers. This works, but my problem is that it leaves an extra paragraph mark on a line by itself at the end of the footer text and I cannot figure out where to add something that would remove the extra paragraph mark. When doing this copy/paste function manually, only a backspace is required to remove the extra paragraph mark. I've tried adding it a few different ways, but it either does nothing or produces an error. The macro text is provided below.
Sub UpdateDocumentFooters()
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 footers
For Each HdFt In Sctn.Footers
With HdFt
If .Exists Then
If Sctn.Index = 1 Then
wdDocSrc.Sections.First.Footers(HdFt.Index).Range.Copy
.Range.PasteAndFormat wdFormatOriginalFormatting
.Range.Characters.Last = vbNullString
ElseIf .LinkToPrevious = False Then
wdDocSrc.Sections.First.Footers(HdFt.Index).Range.Copy
.Range.PasteAndFormat wdFormatOriginalFormatting
.Range.Characters.Last = vbNullString
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
Have reviewed the responses below, but no improvement yet.
I start with this:
Footer to Replace
And want to get this:
Desired Footer
But end up with this:
Resulting Footer

Do a simple calculation in word using VBA

I have many documents i need to edit, i have the Version of the document in the Header like "Version #" these documents have different versions, but are all a single integer value. These versions need to +1 so i need to get the number then just add 1 then save.
This is seeming pretty tricky and im not sure its possible. Any Help would be appreciated.
For example.
Old Document
"Version 2"
New Edit
"Version 3"
I can find and replace as i have learned from here.
Try:
Sub UpdateVersions()
Application.ScreenUpdating = False
Dim strFolder As String, strFile As String, strDocNm As String
Dim wdDoc As Document, wdSctn As Section, wdHdFt As HeaderFooter
strDocNm = ActiveDocument.FullName
strFolder = GetFolder: If strFolder = "" Then Exit Sub
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
If strFolder & "\" & strFile <> strDocNm Then
Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
For Each wdSctn In .Sections
With wdSctn
For Each wdHdFt In .Headers
With wdHdFt
If .LinkToPrevious = False Then
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "Version [0-9]{1,}"
.Replacement.Text = ""
.Format = False
.Forward = True
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
Do While .Find.Found = True
.Text = "Version " & Split(.Text, " ")(1) + 1
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
End If
End With
Next
End With
Next
.Close SaveChanges:=True
End With
End If
strFile = Dir()
Wend
Set wdDoc = 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
This is a quick hack that may do what you wish.
First of all, make sure that you have the Scripting Runtime referenced in the Tools>Project>References menu. Secondly, I have understood that you have more than one document so this lot does everything in a folder.
I have just assumed, for this example, that the folder name is fixed. In Real Life you can modify the code to select the folder and then modify the code to go through sub-folders, but this is (a) a quick hack and (b) out of scope.
Public Sub IncreaseVersionNumbers()
' Make sure that the "Microsoft Scripting Runtime" library is enabled in the Tools>Projects>References
Dim sRootFolder As String
Dim oFSO As Scripting.FileSystemObject
Dim oFolder As Scripting.Folder
Dim oFile As Scripting.File
sRootFolder = "C:\_Documents\VersionNumberTest\" ' You can grab this by a Folder Selection dialog box instead
Set oFSO = New Scripting.FileSystemObject
Set oFolder = oFSO.GetFolder(sRootFolder)
For Each oFile In oFolder.Files
If InStr(1, oFile.Name, ".doc", vbTextCompare) > 0 Then
ProcessDocument (sRootFolder & oFile.Name)
End If
Next oFile
End Sub
Private Sub ProcessDocument(sDocument As String)
Dim oDoc As Word.Document
Dim oSection As Word.Section
Dim oRange As Range
Dim sHeaderText As String
On Error Resume Next
Set oDoc = Documents.Open(sDocument)
For Each oSection In oDoc.Sections
Set oRange = oSection.Headers(wdHeaderFooterPrimary).Range
If Not oRange Is Nothing Then
ProcessHeaderRange oRange
End If
Set oRange = oSection.Headers(wdHeaderFooterFirstPage).Range
If Not oRange Is Nothing Then
ProcessHeaderRange oRange
End If
Set oRange = oSection.Headers(wdHeaderFooterEvenPages).Range
If Not oRange Is Nothing Then
ProcessHeaderRange oRange
End If
Next oSection
oDoc.Close wdSaveChanges
End Sub
Private Sub ProcessHeaderRange(oRange As Range)
Dim sText As String, sNewText As String
Dim nPosn As Long, nStart As Long, nEnd As Long
Dim sVersion As String, nVersion As Long
sText = oRange.Text & " "
nPosn = InStr(1, sText, "Version", vbTextCompare)
If nPosn > 0 Then
nStart = InStr(nPosn, sText, " ")
If nStart > 0 Then
nStart = nStart + 1
nEnd = InStr(nStart, sText, " ")
If nEnd > 0 Then
sVersion = Mid$(sText, nStart, nEnd - nStart)
nVersion = Val(sVersion)
nVersion = nVersion + 1
sNewText = Left$(sText, nStart - 1) & Trim$(Str$(nVersion)) & " " & Right$(sText, Len(sText) - nEnd)
sNewText = Left$(sNewText, Len(sNewText) - 1)
oRange.Text = sNewText
End If
End If
End If
End Sub
This is, as I say, a quick hack so it may not work perfectly but, as always, have backups!
This works by going through each of the three possible headers in each possible section of the document. And if it finds a header in a section then it does what you say.
And this version does go above single digit version numbers. But it's a quick hack, as I say and so needs extra work to make it really bullet-proof. Having said that, it's a reasonable start I would think.
Hope that this helps,
Malc

How to convert a WORD file to .txt with different header?

I have got a lot of word file (~5000) with different header what i read with a macro and merge these multiple word document placed in a folder into one document.
Here the relevant code:
Sub MergeDocs()
Dim rng As Range
Dim MainDoc As Document
Dim strFile As String, strFolder As String
Dim Count As Long
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Pick folder"
.AllowMultiSelect = False
If .Show Then
strFolder = .SelectedItems(1) & Application.PathSeparator
Else
Exit Sub
End If
End With
Set MainDoc = Documents.Add
strFile = Dir$(strFolder & "*.doc") ' can change to .docx
Count = 0
Do Until strFile = ""
Count = Count + 1
Set rng = MainDoc.Range
With rng
.Collapse wdCollapseEnd
If Count > 1 Then
.InsertBreak wdSectionBreakNextPage
.End = MainDoc.Range.End
.Collapse wdCollapseEnd
End If
.InsertFile strFolder & strFile
End With
strFile = Dir$()
Loop
MsgBox ("Files are merged")
lbl_Exit:
Exit Sub
End Sub
It is working, but when I am trying to save file as .txt, the header+footer lose..is it any way which one I can save this header part to a .txt file too? (as I wrote, in every document has got different header.)
EDIT:
Sub MergeDocs()
Dim rng As Range
Dim MainDoc As Document
Dim strFile As String, strFolder As String
Dim Count As Long
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Pick folder"
.AllowMultiSelect = False
If .Show Then
strFolder = .SelectedItems(1) & Application.PathSeparator
Else
Exit Sub
End If
End With
Set MainDoc = Documents.Add
strFile = Dir$(strFolder & "*.doc") ' can change to .docx
Count = 0
Dim doc As Document
Dim head As String, foot As String
Do Until strFile = ""
Set doc = Documents.Open(strFile)
head = doc.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text
foot = doc.Sections(1).Footers(wdHeaderFooterPrimary).Range.Text
doc.Close False
Count = Count + 1
Set rng = MainDoc.Range
With rng
.Collapse wdCollapseEnd
If Count > 1 Then
.InsertBreak wdSectionBreakNextPage
.End = MainDoc.Range.End
.Collapse wdCollapseEnd
End If
.InsertAfter head
.InsertParagraphAfter
.InsertFile strFolder & strFile
.InsertAfter foot
End With
strFile = Dir$()
Loop
MsgBox ("Files are merged")
lbl_Exit:
Exit Sub
End Sub
This is not fully tested but should get you going.
I have only altered your Do loop. Replace, try out and have fun:
Dim doc As Document
Dim head As String, foot As String
Do Until strFile = ""
Set doc = Documents.Open(strFolder & strFile)
head = doc.Sections(1).Headers(wdHeaderFooterPrimary).Range.text
foot = doc.Sections(1).Footers(wdHeaderFooterPrimary).Range.text
doc.Close False
Count = Count + 1
Set rng = MainDoc.Range
With rng
.Collapse wdCollapseEnd
If Count > 1 Then
.InsertBreak wdSectionBreakNextPage
.End = MainDoc.Range.End
.Collapse wdCollapseEnd
End If
.InsertAfter head
.InsertParagraphAfter
.InsertFile strFolder & strFile
.InsertAfter foot
End With
strFile = Dir$()
Loop

Add hyperlinks to linked images

I'm trying to add hyperlinks to images, which were added via IncludePicture fields.
For example, this is an image:
{ IncludePicture "C:\\Test\\Image 1.png" \d }
And so, it should be added hyperlink to it:
C:\\Test\\Image 1.png
After that, I can click on my image in document with mouse, and it will be opened in file manager.
Here is the code. For some reason, it doesn't properly work. How it should be fixed?
Sub AddHyperlinksToImages()
On Error Resume Next
Application.ScreenUpdating = False
Dim iShp As InlineShape
For Each iShp In ActiveDocument.InlineShapes
iShp.Hyperlink.Address = iShp.LinkFormat.SourceFullName 'Doesn't work
'Just for testing
'fullPath = iShp.LinkFormat.SourceFullName
'MsgBox fullPath
Next
Application.ScreenUpdating = True
End Sub
Please try this code.
Sub AddHyperlinksToImages()
' 22 Sep 2017
Dim Fld As Field
Dim FilePath As String
Dim Tmp As String
Dim i As Integer
Application.ScreenUpdating = False
ActiveDocument.Fields.Update
For Each Fld In ActiveDocument.Fields
With Fld
If InStr(1, Trim(.Code), "includepicture", vbTextCompare) = 1 Then
If .InlineShape.Hyperlink Is Nothing Then
i = InStr(.Code, Chr(34))
If i Then
FilePath = Replace(Mid(.Code, i + 1), "\\", "\")
i = InStr(FilePath, "\*")
If i Then FilePath = Left(FilePath, i - 1)
Do While Len(FilePath) > 1
i = Asc(Right(FilePath, 1))
FilePath = Left(FilePath, Len(FilePath) - 1)
If i = 34 Then Exit Do
Loop
If i > 1 Then ActiveDocument.Hyperlinks.Add .InlineShape, FilePath
End If
End If
End If
End With
Next Fld
Application.ScreenUpdating = True
End Sub