If you export Microsoft Entourage contacts to a text file using File > Export > Local contacts, you will have discovered that it does not export the category information for the contacts. There are times when you really need to have the category information (for example, if you then import the text file into Microsoft Excel). One way to get it is to use a script to enter the category names in one of the custom fields that Entourage provides. There are eight of those, and you usually won't need all of them.
For example, if you want to enter category information into the field t hat is named Custom 8 in the UI, you can rename it Categories. To do this, in the Address Book, open any contact, click the Custom 8 label, and then click Edit Label. You can also do that using script. Note that contact (and other Entourage objects) can have more than one category. That's why the category property of the contact class (and of event, task, note, group, and so on) is a list of categories.
For the script below, you need to use a separator when converting the list of category names to text. This script uses a comma but you could use any other separator, such as a semicolon or slash. The way to do this is to
set AppleScript's text
item delimiters
to the chosen separator character (within list braces), and then coerce the list to text.
You then reset the delimiters to whatever they were, namely the default
""
in most cases. You do this afterwards because the delimiters are retained for the entire session (that is, until Quit) of whatever application is running the script (Macintosh Script Editor, Entourage
if run from its menu, System Events if run from the System menu, and so on) and might mess up other scripts if they are not rigorous about setting delimiters before coercing lists to text.
Here is the script:
tell application "Microsoft Entourage"
set custom field eight name of address book 1 to "Categories"
set categoryContacts to every contact ¬
where its category ≠ {}
repeat with i from 1 to (count categoryContacts)
set theContact to item i of my categoryContacts
set catNames to {}
set theCats to category of theContact
repeat with j from 1 to count theCats
set theCategory to item j of theCats
set end of catNames to name of theCategory
end repeat
set AppleScript's text item delimiters to {", "}
set catNames to catNames as Unicode text
set AppleScript's text item delimiters to {""}
set custom field eight of theContact to catNames
end repeat
beep
display dialog All done!" buttons {"OK"} ¬
default button "OK" with icon 1
end tellNote the
where its
instead of
whose
in the second line. In this case, it is mandatory. Otherwise, you get an empty list
{}. This is because Entourage
uses the keyword category for both the category property of the contact class, and for the category class (and for the category property of other objects, too). Every category you create in the UI or by script is a member of the category class.
When used in a
whose
filter, there is a namespace conflict between a class and property of the same name, and AppleScript gives priority to the class over the property. Since there are no contacts that have the category class (they're all of contact class), the result is
{}
— always empty. But by using an equivalent formulation that includes the word
its, thus pinpointing contact, not the application, as the container and category as its property, all becomes clear and you get the result you're looking for. You need to do the same thing when filtering on
every
message of some folder where its account is...
To avoid this conflict, when the Entourage
team created the project class for Entourage 2004, they named the corresponding property project list, which is a property of contact, event, and other classes. Consequently, you can use
whose
in all cases.
Also note the other pronoun
my
in the first line of the
repeat
block. That optimizes iterating through lists, and helps tremendously when the list is large. It can be dozens or hundreds of times faster, so use it. But it only works at the top level of a script, not in a handler unless you declare the list (categoryContacts) as a global variable at the top of the script in which you iterate in a handler.


