Hello, David-Artur
I'm glad you found your way here. You have also now worked out for yourself
that a 'tell' block directed at any object is the equivalent of VBA's 'With'
block, so you've solved over half of your original issues. Similarly, a
'repeat' block can usually be devised equivalent to VBA's 'For Each' loops.
But you have asked about a special case (see below).
First of all, there's no need for a 'using terms' block. That's just for
scripts that are compiled with the (appropriate version of) Microsoft Word
but which may need to run on some other computer that has an unknown version
of Word which might have a different name. You'd then figure out the name of
the application on the new computer (from its creator code, usually) and set
a variable to it, and direct your code at that variable within a 'using
terms' block. There will never be any need for that. All future versions of
Word are guaranteed to be called "Microsoft Word", and, in any case, you've
gone ahead and written 'tell application "Microsoft Word"' anyway! So you
really don't need 'using terms from'. (It's also not going to help you avoid
errors if tried on Word X, if that's what you were hoping.) Did you have
some other reason for 'using terms from'?
What are the circumstances that you'd need an explicit 'on run' handler with
parameters? Will you be calling this script from outside (RealBasic?) in a
way that requires this? More usual would be to not have an explicit 'on run'
handler at all, but to have a regular handler which you can call from either
outside (having loaded the script) or inside, as needed:
on DoThis(findChar, replaceChar, findFont, replaceFont)
--your script here
end
That would let you save the script as a compiled script library, rather than
as an application, and it would run faster, without needing to launch an
application shell. But you may have a good reason - I don't know what RB
requires.
!
OK, yes, you can 'tell settings' instead of using all those repeated 'of'
references. Did you not try it? Does it not work for you? Sometimes it's
helpful to throw in the keyword 'its' in a tell block, and absolutely
necessary to do so if the thing you're referring to might be a class as well
as a property. But it's not necessary here. I just tried your 'tell
settings' block here, and it works perfectly just as you wrote it. (Set the
various AutoFormat settings ON manually in Tools menu/AutoCorrect, then run
the script and check back, and you'll see they've all been unchecked.)
I've never used stories other than the main story, so this is new territory
for me, and I may not be able to test adequately. I'll try. Whatever is
possible in VBA ought to be possible in AppleScript, unless there's a bug -
and if there is, it would be great to find and identify it. Normally, what I
would do would be to get each story, and in a repeat loop call the commands
you specified for only the main story. Sometimes that's more convenient
calling a separate handler (subroutine) to do so - sometimes it's not so
helpful. Either way works.
In this case, it _is_ necessary, since the separate stories are not
available as 'every story of active document'. 'story' is not a class,
stories are not elements (child objects) of document. They seem to live in a
weird counter-culture of their own. ;-) There is a an enumeration 'story
type' used as a parameter to the 'get story range' command. For each story
type you specify, you get a different text range as a result, and you can
then run your 'tell StoryRangeFind' procedure on each range. Because you
have to specify each story type by name, you cannot run a repeat loop on a
list (such as 'every story of theDocument', if story _were_ an element).
Instead having to re-write the whole business 10 times over, call it as a
separate subroutine 10 times:
tell application "Microsoft Word"
tell settings -- only need this once
set auto format as you type replace quotes to false
set auto format as you type replace symbols to false
set auto format as you type replace ordinals to false
set auto format replace quotes to false
end tell
set storyRange to get story range active document story type main text
story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type comments
story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type endnotes
story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type primary
footer story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type primary
header story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type even pages
footer story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type even pages
header story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type first page
footer story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type first page
header story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
set storyRange to get story range active document story type footnotes
story
my ProcessStoryRange(storyRange, findChar, replaceChar, findFont,
replaceFont)
end tell
on ProcessStoryRange(storyRange)
tell application "Microsoft Word"
set StoryRangeFind to find object of storyRange
tell StoryRangeFind
clear formatting
set content to findChar
set name of font object to findFont
set match case to true
set match whole word to false
set match wildcards to false
set match sounds like to false
set match all word forms to false
clear formatting replacement of StoryRangeFind
set content of replacement of StoryRangeFind to replaceChar
set name of font object of replacement of StoryRangeFind to
replaceFont
set language ID of replacement of StoryRangeFind to language no
proofing
execute find replace replace all with find format
end tell
undo clear active document -- Free up some memory.
tell StoryRangeFind -- Clean up
clear formatting
clear formatting replacement of StoryRangeFind
end tell
end tell
end ProcessStoryRange
It is a nuisance that 'story' is merely an enumerated parameter to a command
'get story range;' rather than part of the object model as StoryRange is in
VBA. My guess would be that because there is no such thing as a Collection
Object in AppleScript, there's nothing like VBA's StoryRanges collection
Object for each document. They would have had to create separate 'main text
story', 'comments story' etc etc classes, even there's only one per
document. Or else a 'story' class with 10 enumerated types. Since it's
actually just a text range when all is said and done, it made more sense to
do it as a command with an enumerated parameter.
Now, it turns out that when there are no comments, say, 'get story range
active document story type comments story' errors rather than returning
'missing value' or "". I'll report that as a bug. The workaround is to put
each command in a try block. You can test each one individually to see for
yourself, e.g.:
try
set storyRange to get story range active document story type
comments story
on error
display dialog "No comments story"
end try
Anyway, that's how it is: if you have a primary header, then 'primary header
story' type will have a result, otherwise not. So you need to do something
like this around each handler call:
set storyCheck to false
try
set storyRange to get story range active document story type main
text story
set storyCheck to true
end try
if storyCheck then my ProcessStoryRange(storyRange, findChar,
replaceChar, findFont, replaceFont)
You need to repeat that storyCheck 10 times in the script above.
One thing I have not checked out yet is that in a document with several
sections, each section has its own headers and footers of all the different
flavors - perhaps its own footnotes and endnotes too. Yet 'get story range'
takes only document - not section - as its direct object. I wonder if it
only gets the first section's results that way, or somehow gets the whole
document's. If you test this thoroughly, please let us know. I may check
this too. If you can't do it this way for multi-section documents, you'd
need to get separate headers and footers for each section : 'get header' and
'get footer' in the Text Suite do operate on 'section' and return a 'header
footer' object, then get the 'text object' of each header footer as the
ranges on which to process your Find/Replace routine.
I have not tested thoroughly because I don't have examples for findChar,
replaceChar, findFont, replaceFont as yet. Please let us know how it all
works.
--
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.