How to set the content of a MS-Word bookmark

I’m automating the creation of MS Word document, based on templates. In the template, I have text like “Hi, [your_name], more text…”. The text “[your_name]” needs to be replaced, so in the template I select this text, and insert a bookmark (with the name “your_name”].

In my script, I use the following code to set the value of a bookmark:

tell application "Microsoft Word"
  open rapport_file
  tell document rapport_name
    set content of text object of bookmark "my_bookmark" to "my_value"
  end tell
end tell

However, this will remove the complete bookmark, so I can’t update the document with the same method.

Is there a way to preserve the bookmark?

Why are you modifying the original document?
Make a copy with the Finder before opening your doc or (if the template is saved as a .dotx file in the right place) you can use:

tell application "Microsoft Word"
	set templateFolder to ((get default file path file path type user templates path) & ":") as string
	set myTemplate to (templateFolder & "My templates:myTemplateFile.dotx") as string
	set myDoc to (create new document attached template myTemplate)
end tell

The template path has to be a text (not an alias) otherwise it will make an error.
The Template file must be of dotx or dotm format.


I already make a copy of the original template. That is not the problem.

When I created a document, and filled out all bookmarks, I would like to have the option to, at a later time, update the filled out bookmarks.

For example, I have a bookmark “address”. After the document is created, somebody notices a typo in the address in the database. In such a case it would be nice to update the document, instead of re-creating it. The latter is unwanted, because the document could already have been editted.

Can you do this manually in Word?
If so, then record a Word VBA Macro as you do it.
Then you can edit that Word Macro as needed. You can call the Word Macro from an AppleScript if you like.

OTOH, the Word Macro may provide you with the info to make the same change from AppleScript.


(Sorry for responding so late.)

The only way is to re-create the bookmark.
I hope you don’t work with ID but with name of bookmarks.
Try this:

tell application id "MSWD"
	set aBook to bookmark 1 of active document -- or bookmark 1 of selection
	set aStart to start of bookmark of aBook
	set aName to name of aBook
	set newContent to "some other text "
	set newLength to length of newContent
	set content of text object of aBook to newContent
	set myRange to create range active document start aStart end aStart + newLength
	set newBook to make new bookmark at myRange with properties {name:aName}
	select myRange
	return newBook
end tell

Tested with Word 2011.

(sorry for the very very late response. I’ve been busy with other things)

Thanks for the answer. This is what I need!
Re-creation is the way to go. It’s build in my script now, and it works in Word 2016 also!

This solution is going to save a lot of problems, because now we update documents with AppleScript, when some details change in time…


[Why can’t we post with just a smiley?]

Everything works fine, except that I ran in to a problem. When I replace a bookmark that is defined in a footer, something weird is going on. The text is replaced, as expected, but the bookmark itself is re-defined in the beginning of the document.

I suspect this has to do with the “story type” property of bookmark, but for some reason it doesn’t seem to work. My code:

on msword_change_bookmark(doc, bm, new_text as text)
  using terms from application "Microsoft Word"
    tell doc
      if (content of text object of bm) ≠ new_text then
        set bm_start to start of bookmark of bm
        set bm_end to bm_start + (length of new_text)
        set bm_name to name of bm
        set bm_story_type to story type of bm
        -- overwrite old bookmark with new text
        set content of text object of bm to new_text
        set my_range to create range doc start bm_start end bm_end
        set new_bm to make new bookmark at my_range with ¬
            properties {name:bm_name, story type:bm_story_type}
      end if
    end tell
  end using terms from
end msword_change_bookmark