Word 2004 and AppleScript

J

Jim Jaeger

Is there any documentation available for AppleScripting Word 2004. I've
Googled, searched the newsgroups, and looked on forums. I can find
nothing.

The AppleScript dictionary in Word 2004 is opaque to me.

My task is to script global script and replace for several words in
several documents. It should be easy, but I can't understand the AS
dictionary.

Thanks.

jim
 
M

matt neuburg

Jim Jaeger said:
Is there any documentation available for AppleScripting Word 2004. I've
Googled, searched the newsgroups, and looked on forums. I can find
nothing.

Paul Berkowitz tells me (and he'll probably show up here any moment now)
that the Microsoft folks will come out with a reference document one of
these days. Until then, there's nothing because it's all too new.
The AppleScript dictionary in Word 2004 is opaque to me.

You'll have a much easier time if you look at it (or even better, at a
Word document) with Script Debugger. This shows you the actual object
model graphically.

Another helpful approach is to learn a little Visual Basic (for Word).
The AppleScript model is basically just an expression of the VB model.
The little diagrams in Visual Basic help, or the object browser in VB,
actually help you with AppleScript.
My task is to script global script and replace for several words in
several documents. It should be easy, but I can't understand the AS
dictionary.

I'll be glad to assist. Describe more precisely what you want to do -
keep it short, please, perhaps a subset of your task - and I'll try to
show you how to write it. That will help get you going (with luck). m.
 
P

Paul Berkowitz

Is there any documentation available for AppleScripting Word 2004. I've
Googled, searched the newsgroups, and looked on forums. I can find
nothing.

The AppleScript dictionary in Word 2004 is opaque to me.

My task is to script global script and replace for several words in
several documents. It should be easy, but I can't understand the AS
dictionary.

There is supposed to be an exhaustive Reference coming. As you can imagine
it's bound to be enormous, and it's taking a long time to produce. In the
meantime, you have two alternatives:

1) Since the object model is virtually identical to that used for Word's
VBA, open up VB Editor (Tools/Macro/Visual Basic Editor), then the VBA Help.
The VB term will be almost identical to the AppleScript term, but instead of
"insert break" or "heading style" looks like "InsertBreak" and
"HeadingStyle". You get the idea: no spaces between words and capitalized.
The VB Help is very good - it explains how the Objects (Classes) and Methods
(commands) and Properties work, and especially the various arguments
(parameters) and enumerations (defined constants) that go with them . In VB
the values are linked to the arguments by ":=" - ignore that. In AppleScript
everything just runs on. The VB Help also contains a lot of good examples
(and a few poor examples).

2) Ask here. There are a few of us here who are finding our way about. If we
don't know the answer we can probably figure it out. Maybe.

--
Paul Berkowitz
MVP Entourage
Entourage FAQ Page: <http://www.entourage.mvps.org/faq/index.html>
AppleScripts for Entourage: <http://macscripter.net/scriptbuilders/>

Please "Reply To Newsgroup" to reply to this message. Emails will be
ignored.

PLEASE always state which version of Entourage you are using - **2004**, X
or 2001. It's often impossible to answer your questions otherwise.
 
P

Peter Edman

I'll be glad to assist. Describe more precisely what you want to do -
keep it short, please, perhaps a subset of your task - and I'll try to
show you how to write it. That will help get you going (with luck). m.


Can I jump in with a request since we're on the topic? I'm reformatting
a Gutenberg Project text and am trying to use Applescript to get Word
2004 to take the selected text (or any text between square brackets) and
make it into a footnote. I can do it in VBscript (well, by recording and
editing a macro). I thought I could read the AppleScript library, and my
script compiles in the Script Editor, but I get the error message:
"Cannot make a footnote" no matter how I try.

Any ideas on how to create a footnote are more than welcome.
thanks
Peter E.
 
M

matt neuburg

Peter Edman said:
Can I jump in with a request since we're on the topic? I'm reformatting
a Gutenberg Project text and am trying to use Applescript to get Word
2004 to take the selected text (or any text between square brackets) and
make it into a footnote. I can do it in VBscript (well, by recording and
editing a macro). I thought I could read the AppleScript library, and my
script compiles in the Script Editor, but I get the error message:
"Cannot make a footnote" no matter how I try.

Any ideas on how to create a footnote are more than welcome.

Okay. First, grab the text you want to be a footnote. Remember it as a
variable (let's call it myText) and remove it from the document. Now
position the insertion point where you want it. The footnote will be
inserted after the selection or insertion point. Now say this:

tell application "Microsoft Word"
set f to (make new footnote at document 1)
set content of text object of f to myText
end tell

m.
 
P

Peter Edman

Thank you for this, Matt. Very much!

For any interested observers, the following takes the selection and
turns it into a footnote while retaining formatting (or creates a
footnote at the insertion point):

tell application "Microsoft Word"
set myText to formatted text of content of selection
set xfoot to (make new footnote at document 1)
set formatted text of content of text object of xfoot to myText
set myText to delete myText
end tell

I found it interesting -- frustrating -- that if you try to enclose this
in a "tell document 1" segment, you get a "missing value" returned for
the selection. Apparently, "selection" is not an element of "document".

Also frustrating is that "contents" returns missing value while
"content" produces the proper result. But both compile fine.

Now on to learn how to find all the text ranges enclosed by square
brackets . . .

cheers
Peter E.
 
P

Paul Berkowitz

Actually, I answered this two days ago where you first asked this, Peter -
on Rick Schaut's blog. Did you not go back to check?

I include there how you'd make a footnote at somewhere other than the cursor
location in the document, for example at the end of the first paragraph:

tell application "Microsoft Word"
set oDoc to active document
set t to text object of paragraph 1 of oDoc
set f to make new footnote at t
set content of text object of f to "Here's another footnote."
end tell

There's a lot more info there. Instead of my repeating it, just go there to
check

http://blogs.msdn.com/rick_schaut/archive/2004/06/25/165528.aspx#FeedBack

You should not find it frustrating that you can't get 'selection of document
1', as you certainly can in some applications. You (all of us) need to
spend time checking things in the dictionary. Word's Object Model does not
allow for selections in different documents. There is only one selection in
the application - and that's in the front document. (You can see this even
in the UI: when you click on another doc, the selection in the formerly
front doc disappears.) So 'selection' is a property only of 'application' -
where you'll find it. If it were also a property of 'document', then every
single open doc could have it's own selection. (Some apps do allow this.) I
think that things are probably the way they are to emphasize that using
'selection' is something that mimics a user in the UI - there's only one
selection, and that's in the front window. It's not in fact the best way to
control Word. You should spend some time learning about 'text range' : the
most essential object in all of Word's scripting and (as 'Range') VBA. In
AppleScript, it's usually accessed as the 'text object' property of all
sorts of things - document, paragraph, etc. You can adjust properties, and
make footnotes, at any range in any document - it doesn't have to be in the
front, and nothing needs to be selected.

It's _very_ sensible of the Word developer to have used 'content' rather
than 'contents'. Many applications run into trouble when they use 'contents'
instead, since it's also an AppleScript language keyword that simply
dereferences a reference. (For example, if you script

set the List to {1,2,3}
set x to 3
repeat with anItem in theList
if anItem = x then
display dialog (x as string)
end if
end repeat

you'll never get that dialog. But if you use

if (contents of anItem) = x

then you will.)

What this means is that in some applications, when you ask for 'contents' of
something, you just get the same thing back again. That's why you got the
error. (In AppleScript Studio, you have to ask for 'contents of contents' to
actually get what you want!) By making a distinction between AppleScript's
'contents' and Word's own 'content' property, you'll never hit that
conflict. Because 'contents' is an AppleScript language keyword, it compiles
fine in all times and places and tell blocks. That's not Word's fault. The
fact that something compiles does not mean it's the correct term. (Not only
do you have to watch out for AppleScript keywords, but also for scripting
addition commands, which will also compile.)

Just make no assumptions, and study the dictionary. It's hard-going, but
eventually you start to get the strange logic of it all.

But learning about Word's 'find' and 'replace' commands are among the most
knotty complicated things in the object model. Do check up in the VBE Help,
and also in the VBA pages at http://www.word.mvps.org/ . (You have to
refresh a couple of times for each page there in Safari, or else use IE.)


--
Paul Berkowitz
MVP Entourage
Entourage FAQ Page: <http://www.entourage.mvps.org/faq/index.html>
AppleScripts for Entourage: <http://macscripter.net/scriptbuilders/>

Please "Reply To Newsgroup" to reply to this message. Emails will be
ignored.

PLEASE always state which version of Entourage you are using - **2004**, X
or 2001. It's often impossible to answer your questions otherwise.
 
P

Paul Berkowitz

For any interested observers, the following takes the selection and
turns it into a footnote while retaining formatting (or creates a
footnote at the insertion point):

tell application "Microsoft Word"
set myText to formatted text of content of selection
set xfoot to (make new footnote at document 1)
set formatted text of content of text object of xfoot to myText
set myText to delete myText
end tell

OK, now to your script. I'm glad you got it to work, but there are a few
things that can be cleaned up. Here the two uses of 'content' are
unnecessary and redundant. Actually it's lucky that the first one doesn't
strip the formatting, or error - it's just ignored.

'content' property of 'selection object' and of 'text range' is of 'Unicode
text' class - it's just supposed to give you the straight text without
formatting. (Unicode has nothing to do with formatting. Here you're using
plain English, so the result would look the same as plain text in both Word
and in any script editor.) Fortunately Word helps you out here by correctly
assuming you in fact mean 'formatted text of selection'. You'll notice that
'formatted text' _is_ a property of selection object and of text range,
whereas Unicode text and string (both AppleScript terms for the obvious
things) don't have any such property. Again, you should be setting the
'formatted text' property of your footnote's text object, not the content of
this property - which would be just the plain text aspect.

Somewhat to my surprise, Word is coercing nicely and it works. But sooner or
later you will run into trouble. Also, just for once, the correct way is
actually simpler than your version. This is it (and it works too!):

tell application "Microsoft Word"
set myText to formatted text of selection
set xfoot to (make new footnote at active document)
set formatted text of (text object of xfoot) to myText
delete myText
end tell

Another couple of changes I made: 'active document' for the front document,
not 'document 1'. You may have had just one doc open. Try now opening a
second document and repeating this there, with the previous doc still in
the background. You'll now get into a muddle since 'document 1' (it's the
one that was _opened first_) is in the background, but your selection is in
the front document - which Word knows as document 2 since it was made
second. Or document 9, or whatever. Word docs keep the index they were born
with when you opened them (and that's not the same as the title "Document1"
either: the UI does not re-title a saved doc as "Document1" when you open it
but it will still be indexed as 1 by AppleScript).

Finally you must not set a variable (myText) to the 'delete' command, since
that's one command that never has a result. (You'll see your script editor
ends up with <undefined> as the result.) It can't - since the object doesn't
exist any more. Again, that should really error, but Word is being very
friendly and lets it pass. I thought only the Finder did this. ;-) Some
people think these "lax" methods are good - they're certainly appreciated by
beginners. But Word scripting is not really for beginners, and you may end
up in trouble if you get used to things like this that sometimes work and
sometimes don't. In my opinion, it's better to learn to do things right.

There are other ways to delete the selected text too, but it's nice this
simpler way works too. (You're ostensibly just deleting the formatted text
property of the selection, not the whole selection, but it works fine.)

--
Paul Berkowitz
MVP MacOffice
Entourage FAQ Page: <http://www.entourage.mvps.org/faq/index.html>
AppleScripts for Entourage: <http://macscripter.net/scriptbuilders/>

Please "Reply To Newsgroup" to reply to this message. Emails will be
ignored.

PLEASE always state which version of Entourage you are using - **2004**, X
or 2001. It's often impossible to answer your questions otherwise.
 
J

Jim Jaeger

Paul Berkowitz said:
There is supposed to be an exhaustive Reference coming...In the
meantime...

1)...open up VB Editor (Tools/Macro/Visual Basic Editor), then the VBA Help.
The VB term will be almost identical to the AppleScript term, but instead of
"insert break" or "heading style" looks like "InsertBreak" and
"HeadingStyle". You get the idea: no spaces between words and capitalized.
...In AppleScript everything just runs on. The VB Help also contains a lot
of good examples...

2) Ask here...

Thanks for the pointers to getting started. I'm afraid, however, that I
don't "get the idea". I've gone to the VBA editor to look things up. I'm
not sure it helped. So far, I have (besides reviewing chapter 3 of
_AppleScript_the_Definitive_Guide_), recorded and run a macro that is a
subset of my problem, and attempted to convert that macro into something
AS would handle. I've failed repeatedly.

The larger problem is to compile a personnel directory from a FileMaker
Pro database. Over time, I've developed scripts for FMP that extract the
data I need to tab-delineated text files. As things stand, I can extract
the data from FMP and get Word2004 to open the file.

A sample line of the data (one record of many) might look like this:

Masterson , George ( Phyllis ) 524-1461 * 9876 Calle
Ennui Filmore 93066 * (e-mail address removed) *
Personal/Data/About/George

There are tabs and spaces imbedded in there that do not show, of course,
the "*" get concerted to "soft return (^l)", and there are no line
breaks . The record ends with a "return (^p)". I have evolved a series
of steps that sort out the unwanted tabs (some, I need to keep) and
spaces to make the entry look like this:

Masterson, George ( Phyllis ) 524-1461
9876 Calle Ennui Filmore 93066
(e-mail address removed)
Personal/Data/About/George

When the data gets cleaned up, it will be pasted into a Word document
template and I'll apply styles and make other formatting adjustments.

The macro to accomplish the first step, get rid of the tabs around the
comma, works and takes this form:

Sub FindAndReplace()
'
' FindAndReplace Macro
' Macro recorded 7/14/04 by James Jaeger
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "^t, ^t" : REM tab comma space space tab
.Replacement.Text = ", " : REM comma space space
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub

I've tried for hours to beat this macro into a form that AS understands.
Take out dots, remove equal signs, run words together, add equal signs,
remove spaces, curse, kick dog, etc. Nothing, so far, has worked. I
really wanted to solve this on my own, but the solution has eluded me.

How do I get from this working macro to "native" AS?

jim
 
P

Peter Edman

Paul Berkowitz said:
Actually, I answered this two days ago where you first asked this, Peter -
on Rick Schaut's blog. Did you not go back to check?

Hadn't yet. Wasn't actually expecting a response. You're too kind. The
info there is most helpful.
You should not find it frustrating that you can't get 'selection of document
1', as you certainly can in some applications. You (all of us) need to
spend time checking things in the dictionary. Word's Object Model does not

Well, I can come to appreciate it as I understand more about it, but
that doesn't make it less frustrating at the time :)

I've spent the past few months coming up to speed with AppleScript
mostly by using InDesign CS -- which, being out there longer than Word
2004, naturally has far more extensive documentation and an active forum
dedicated to helping people script it. So I'm carrying over my
expectations from that (more document-centric) object model.
control Word. You should spend some time learning about 'text range' : the
most essential object in all of Word's scripting and (as 'Range') VBA. In

Will begin working on that.
It's _very_ sensible of the Word developer to have used 'content' rather
than 'contents'. Many applications run into trouble when they use 'contents'

That's a helpful explanation. I expect that as soon as more example
scripts and (responsible deity willing) the reference guide begin to
emerge, frustration levels will decrease and appreciation for the
developer will increase.
But learning about Word's 'find' and 'replace' commands are among the most
knotty complicated things in the object model. Do check up in the VBE Help,

Well, at least you're not promising us an easy time of it!
and also in the VBA pages at http://www.word.mvps.org/ . (You have to
refresh a couple of times for each page there in Safari, or else use IE.)

I use Mozilla. It seems to load the pages just fine. Thanks again for
this, and for the corrections to my script.

Peter E.
 
M

matt neuburg

Jim Jaeger said:
The macro to accomplish the first step, get rid of the tabs around the
comma, works and takes this form:

Sub FindAndReplace()
'
' FindAndReplace Macro
' Macro recorded 7/14/04 by James Jaeger
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "^t, ^t" : REM tab comma space space tab
.Replacement.Text = ", " : REM comma space space
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub

How do I get from this working macro to "native" AS?

It translates almost word for word directly into AS:

tell application "Microsoft Word"
set f to (get find object of selection)
tell f
clear formatting
set content to "^t, ^t"
set r to (get replacement of f)
tell r
clear formatting
set content to ", "
end tell
set forward to true
set wrap to find continue
set format to false
set match case to false
set match whole word to false
set match wildcards to false
set match sounds like to false
set match all word forms to false
execute find replace replace all
end tell
end tell

m.
 
J

Jim Jaeger

It translates almost word for word directly into AS:

tell application "Microsoft Word"
set f to (get find object of selection)
tell f
clear formatting
set content to "^t, ^t"
set r to (get replacement of f)
tell r
clear formatting
set content to ", "
end tell

<snip again>

set match sounds like to false
set match all word forms to false
execute find replace replace all
end tell
end tell

Thanks for the kick-start, Matt and Paul.

In case someone else has the same problem I had, my mistake was in not
looking at the Word AS dictionary as I tried to convert from Visual
Basic to AppleScript. Once Matt demonstrated the conversion and I went
back to the dictionary, things cleared up quickly.

With luck, that one is behind me.

As Matt and Paul probably know, Matt's conversion works swimmingly. I've
made it a subroutine and cleaning up the FMPro output is complete.

Thanks again.

jim
 
E

Elliott Roper

Jim said:
Thanks for the kick-start, Matt and Paul.

In case someone else has the same problem I had, my mistake was in not
looking at the Word AS dictionary as I tried to convert from Visual
Basic to AppleScript. Once Matt demonstrated the conversion and I went
back to the dictionary, things cleared up quickly.

With luck, that one is behind me.

As Matt and Paul probably know, Matt's conversion works swimmingly. I've
made it a subroutine and cleaning up the FMPro output is complete.

Thanks again.

Me too. I was only lurking, but this discussion has been *very*
educating.

PS to Matt. Your book followed me home from the bookshop a couple of
days ago. I love it. ;-)
 
M

matt neuburg

The power of an example...! As Paul has been at pains to stress, there
is really is a remarkably one-to-one correspondence between VBA and the
new AS model. You just have to know a few key terms like "content" for
"text" and the translation almost (though not quite) writes itself. This
is an amazing accomplishment on the part of the Mac BU guy who did this,
esp. when you consider that certain constructs work very differently in
the two languages.
PS to Matt. Your book followed me home

Let it hang around with a VBA book for a while and you'll soon have
Word-scripting puppies! m.
 
J

Jim Jaeger

The power of an example...! As Paul has been at pains to stress, there
is really is a remarkably one-to-one correspondence between VBA and the
new AS model. You just have to know a few key terms like "content" for
"text" and the translation almost (though not quite) writes itself. This
is an amazing accomplishment on the part of the Mac BU guy who did this,
esp. when you consider that certain constructs work very differently in
the two languages.


Let it hang around with a VBA book for a while and you'll soon have
Word-scripting puppies! m.

Matt, have you started on the "Take Control" e-book on the subject?

jim
 
D

Dayo Mitchell

Elliott Roper said:
Me too. I was only lurking, but this discussion has been *very*
educating.
Me three. Also lurking and saved the messages for when I get that far into
Applescript...

Dayo
 
M

matt neuburg

Jim Jaeger said:
Matt, have you started on the "Take Control" e-book on the subject?

I told Paul I thought *he* should write it! He really is the expert on
this. m.
 
P

pereljon

Here's an issue that's been stumping me for a while now...
How are you able to get Microsoft Word 2004 to perform a replace across
all the story elements of a document. Lets say you want to replace a
name not just in the main text of a Word document, but also in the
headers and footers... I've tried the following with no success...

tell application "Microsoft Word"
repeat with theType from 0 to 10
try
set myRange to get story range active document story type theType
set f to (get find object of selection)
tell f
clear formatting
set content to "a"
set r to (get replacement of f)
tell r
clear formatting
set content to "b "
end tell
set forward to true
set wrap to find continue
set format to false
set match case to false
set match whole word to false
set match wildcards to false
set match sounds like to false
set match all word forms to false
execute find replace replace all
end tell

end try
end repeat
end tell


I've tried using the "set all documents to true" setting. This replaces
across headers and footer, but often times crashes Word 2004. I would
love to be able to AppleScript a replace across open documents, but
either this is buggy or I'm doing something my AppleScript crashes
Word.

1. Any suggestions for replacing across all existing story ranges in a
Word document with AppleScript?
2. Any ideas how to replace across all open documents?

Thanks!
JP
 
D

Daiya Mitchell

An ordinary Find & Replace in Word will search all story elements. Are you
sure you need to specify the ranges, just because you are doing it through
applescript?
 
P

Paul Berkowitz

Some comments (putting to one side Daiya's comment which may very well be
apposite):

1) If you are trying to debug a script that's not getting you what you want,
NEVER put the whole thing in a try/end try block. You'll never learn
anything that way. You want the script to error on a specific word of a
specific line so you can figure out what's wrong. After you've got it
working perfectly, you may want to introduce a try/on error block that at
least provides a useful way of dealing with expected and unexpected errors.
But not now.

2) If it turns out that certain passes through the repeat loop might be
expected to error, and you do want just those passes to skip without an
error message, you need a way to move on to the next iteration. AppleScript
does not have a 'Next' command but you can create a trick version this way:

repeat with i from 1 to (count someList)
repeat 1 times
set someVar to item i of someList
try -- or if...
-- do stuff
on error -- or else
exit repeat -- exits just the '1 times' loop
end try -- or if
end repeat
-- maybe more stuff
end repeat

3) You are using integers for theType. Now it's possible that the
AppleScript enumerations for the 'story type' parameter given in the
dictionary -

main text story/footnotes story/endnotes story/comments story/text frame
story/even pages header story/primary header story/even pages footer
story/primary footer story/first page header story/first page footer story

_may_ be mapped to integers "under the hood". But have you tested them, or
arte you just "hoping", or have you taken this from VBA? In AppleScript, I
would be extremely surprised to find the integer '0' being used, since
AppleScript is almost all 1-based. I haven't tested myself, so I don't know
for sure that the developer did not use '0', but frankly, I'd just avoid
integers and use the actual enumerations as given above. (You could put them
all in a list, and then fetch 'item i' of the list, with i from 1 to 11, not
0 to 10.)

Due to reason 1) above, all you needed was one error, and the whole script
goes kaput because of your try/error block. theType being 0 could have been
such an error.

4) If you check the Word AppleScript Reference (available from MacTopia),
you'll see that it says the following about 'story range' on p. 272:

"If you attempt to return a story that isn't available in the specified
document, an error occurs."

Aha! Therefore you should _expect_ errors for some of the repeat loops. You
need to be able to escape from just those loop iterations if that happens,
not the whole script.

So, first check to see if you can use numbered iterations or not (point 3)
above) and if so whether they should be 0 to 10 or 1 to 11.

Then re-write your repeat loop to include an inner 'repeat 1 times' loop
that does exit (or even just end try) and then moves on to the next
iteration (story type).

5) Check out Daiya's query - is it really necessary to do this for each
story type separately?


--
Paul Berkowitz
MVP MacOffice
Entourage FAQ Page: <http://www.entourage.mvps.org/faq/index.html>
AppleScripts for Entourage: <http://macscripter.net/scriptbuilders/>

Please "Reply To Newsgroup" to reply to this message. Emails will be
ignored.

PLEASE always state which version of Microsoft Office you are using -
**2004**, X or 2001. It's often impossible to answer your questions
otherwise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top