Microsoft Word, Find and Replace all in headers

Hi,

I’m trying to do an applescript that allows me find and replace all occurences of a string. I can do it in the main text, but I cannot get it to work in headers and footers. I’ve tried things like this … but to no avail.

textToFind and texttoReplaceWith are defined

on WordFindReplace(textToFind, texttoReplaceWith)
	tell application "Microsoft Word"
		set myFind to find object of text object get footer index header footer primary
		tell myFind
			clear formatting
			set style of myFind to header footer primary
			execute find myFind find text (textToFind as text) replace with texttoReplaceWith replace replace all with wrap find
		end tell
	end tell
end WordFindReplace

Ideas? An hour or more of looking for script snippets, and I’m coming up empty.

Thanks!

Neil

Hi Niel,

The following code will get the contents of a header in word and will also change the text. Hopefully this puts you on the right track!


tell application "Microsoft Word"
	activate
	set doc to front document
	
	set headerText to content of text object of (get header of section 1 of doc index header footer primary)
	-- This line will set the header text to the variable "headerText"
	
	set content of text object of (get header of section 1 of doc index header footer primary) to "hello world"
	-- This line will actually update the text in the header
end tell

Thanks Adam!

The issue I’m having is how to do a find/replace (all) in the main text and header/footer (both first page only, and general).

Any ideas how to do that?

Thanks!

Neil

I had a crack at writing something for you on the train home. Is this roughly what you are looking for?


set xFind to "TEXT YOU WANT TO FIND"
set xReplace to "REPLACE TEXT"

tell application "Microsoft Word"
	activate
	set doc to front document
	
	set headerText to content of text object of (get header of section 1 of doc index header footer primary)
	-- This line will set the header text to the variable "headerText"
	
	set footerText to content of text object of (get footer of section 1 of doc index header footer primary)
	-- this line will set the variable "footerText"
	
	set bodyText to content of text object of doc
end tell

set headerText to replaceText(xFind, xReplace, headerText)
set footerText to replaceText(xFind, xReplace, footerText)
set bodyText to replaceText(xFind, xReplace, bodyText)

tell application "Microsoft Word"
	activate
	set doc to front document
	set content of text object of (get header of section 1 of doc index header footer primary) to headerText
	set content of text object of (get footer of section 1 of doc index header footer primary) to footerText
	set content of text object of doc to bodyText
end tell


on replaceText(find, replace, subject)
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to find
	set subject to text items of subject
	
	set text item delimiters of AppleScript to replace
	set subject to subject as text
	set text item delimiters of AppleScript to prevTIDs
	
	return subject
end replaceText

Very close!!! Thank you so much for the magic language in identifying.
For completeness, this version will handle ALL the types of header/footers as well as the body.
To make it super clear to see – I appended the xReplace text with where it was replacing (e.g., “-Primary”)


set xFind to "TEXT YOU WANT TO FIND"
set xReplace to "REPLACE TEXT"

tell application "Microsoft Word"
	activate
	set doc to front document
	
		set headerTextPrimary to content of text object of (get header of section 1 of doc index header footer primary)
		set footerTextPrimary to content of text object of (get footer of section 1 of doc index header footer primary)
		set headerTextFirstPage to content of text object of (get header of section 1 of doc index header footer first page)
		set footerTextFirstPage to content of text object of (get footer of section 1 of doc index header footer first page)
		set headerTextEvenPages to content of text object of (get header of section 1 of doc index header footer even pages)
		set footerTextEvenPages to content of text object of (get footer of section 1 of doc index header footer even pages)
		set bodyText to content of text object of doc
end tell

set headerTextPrimary to replaceText(xFind, xReplace & "-Primary", headerTextPrimary)
set footerTextPrimary to replaceText(xFind, xReplace & "-Primary", footerTextPrimary)
set headerTextFirstPage to replaceText(xFind, xReplace & "-FirstPage", headerTextFirstPage)
set footerTextFirstPage to replaceText(xFind, xReplace & "-FirstPage", footerTextFirstPage)
set headerTextEvenPages to replaceText(xFind, xReplace & "-EvenPages", headerTextEvenPages)
set footerTextEvenPages to replaceText(xFind, xReplace & "-EvenPages", footerTextEvenPages)
set bodyText to replaceText(xFind, xReplace & "-Body", bodyText)

tell application "Microsoft Word"
	activate
	set doc to front document
	set content of text object of doc to bodyText
	set content of text object of (get header of section 1 of doc index header footer first page) to headerTextFirstPage
	set content of text object of (get footer of section 1 of doc index header footer first page) to footerTextFirstPage
	set content of text object of (get header of section 1 of doc index header footer primary) to headerTextPrimary
	set content of text object of (get footer of section 1 of doc index header footer primary) to footerTextPrimary
	set content of text object of (get header of section 1 of doc index header footer even pages) to headerTextEvenPages
	set content of text object of (get footer of section 1 of doc index header footer even pages) to footerTextEvenPages
end tell


on replaceText(find, replace, subject)
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to find
	set subject to text items of subject
	
	set text item delimiters of AppleScript to replace
	set subject to subject as text
	set text item delimiters of AppleScript to prevTIDs
	
	return subject
end replaceText


BUMMER! It doesn’t work in production. It changes the formatting for the text, blows out pictures, and more. Thoughts?

That’s because the script is only getting the content as plain text. A Word text range can contain more than just plain text.

Try something like this and adjust accordingly:

tell application "Microsoft Word"
	
	tell active document
		
		tell section 1
			
			repeat with whichHeaderFooter in {header footer primary, header footer first page, header footer even pages}
				execute find (find object of (text object of (get header index whichHeaderFooter))) ¬
					find text "hello" replace with "goodbye" replace replace all
				execute find (find object of (text object of (get footer index whichHeaderFooter))) ¬
					find text "hello" replace with "goodbye" replace replace all
			end repeat
			
		end tell
		
	end tell
	
end tell

Excellent – thanks Roosterboy! For completeness, I’ve extended this to work for all sections in the document, using the same setup as before.



set xFind to "TEXT YOU WANT TO FIND"
set xReplace to "REPLACE TEXT"

tell application "Microsoft Word"
	
	tell active document
		set numberOfSections to number of sections
		log ("••••• There are " & numberOfSections & " in this document.")
		repeat with curSectionNum from 1 to numberOfSections
			log ("••••• Section: " & curSectionNum & " - Begin search and replace")
			tell section curSectionNum
				execute find (find object of (text object)) ¬
					find text xFind replace with xReplace replace replace all
				
				repeat with whichHeaderFooter in {header footer primary, header footer first page, header footer even pages}
					execute find (find object of (text object of (get header index whichHeaderFooter))) ¬
						find text xFind replace with xReplace replace replace all
					execute find (find object of (text object of (get footer index whichHeaderFooter))) ¬
						find text xFind replace with xReplace replace replace all
				end repeat
			end tell
		end repeat
	end tell
	
end tell