You can select Flag for Follow Up on the Tools menu in Microsoft Word, Excel, and PowerPoint, and this creates an Entourage task for your document that can send you a reminder about it. However, Entourage itself does not have the same utility, except with e-mail messages.
Calendar events and tasks have their own reminders, which is the same thing. But there is no way to flag a contact other than by setting the red flag. There's no Flag for Follow Up menu item to make a task with a reminder for the contact — say, as a reminder that you need to e-mail them, phone them, or write a letter.
The following script can do it by making a task with a reminder in just the same way, carrying over the contact name and a prospective reminder time, which you can change, and linking the task to the contact.
-- Prepare the times of the due date and reminder
set now to current date
copy now to today
set time of today to 0 -- midnight
set nextHour to (((time of now) div hours) + 1) * hours
set time of now to nextHour -- on the hour
tell application "Microsoft Entourage"
try
--get the selected contact(s)
set theContacts to (get selection)
--check that they are actually contacts
if class of (item 1 of theContacts) ≠ contact then ¬
error number -128
on error
beep
display dialog "First select a contact before running " & ¬
"the script." buttons {"Cancel"} default button 1 ¬
with icon 0
return
end try
repeat with theContact in theContacts
repeat 1 times -- to allow for skipping contacts
if class of theContact ≠ contact then exit repeat
set theName to name of theContact
(* if the contact has no name, check for
nickname, company, email address, IM address
in that order until you find one *)
if theName = "" then set theName to nickname of theContact
if theName = "" then set theName to company of theContact
try
if theName = "" then set theName ¬
to email address 1 of theContact
end try
try
if theName = "" then set theName to ¬
instant message address 1 of theContact
end try
--if still no name, forget this one
if theName = "" then exit repeat
-- go on to next one
--set a red flag
set flagged of theContact to true
-- make the task with the info
-- get the contact's categories and projects along the way
set theTask to make new task with properties {name:¬
("Flagged Contact: " & theName), due date:¬
today, remind date and time:now, category:¬
(get category of theContact), project list:¬
(get project list of theContact)}
link theTask to theContact
open theTask
end repeat
end repeat
end tellThe first section of the script prepares the times for the due date and reminder of the task to be created. If possible, it is best to perform date manipulations outside of application
tell
blocks; otherwise, you may hit errors. (If you do, and can't extricate yourself from the
tell
block, try
tell AppleScript to ..., which sometimes works.) Unlike all other data types in AppleScript, dates, along with lists, records, and script objects, are mutable when variables are set to them.
Since you want two different dates (times) to be derived from the variable
now, which is set to the current time (current date), you need to copy, not set, the variable
now
to
today. Otherwise, any changes you make to
today
would also occur with
now.
The
now
and
today
variables are date objects, meaning date-and-time. By setting the time of
today
to
0, you change its time, which is calculated in integer seconds, to midnight. (Task due dates need to be set to midnight of the day in question.)
With the other date variable
now, you need to use date arithmetic. You preset the prospective reminder time to the upcoming hour — not an hour from
now, which is probably something like 3:14:47 PM, but right on the hour (3:00:00 PM). AppleScript has the constants minutes, hours, days, weeks, which are just integers, namely the number of seconds in those units of time (60, 3600, 86400, 604800 respectively). So, you don't have to remember or calculate them every time that you need them.
You use the operator
div
to get the whole-number integer part of the dividend of
now's time when divided by hours (3600), which is the hour of the current time (for example, 14 for 2:00 pm). You then add 1 (to make 15), multiply that again by hours (3600) to get the number of seconds at 3:00 pm, and make that the new time of
now. If the time of
now
is after 23:00, this procedure automatically rolls over to 0:00 of the next day, with the day and date advancing.
The next part of the script first gets the selection. The selection can be a list of items such as contacts, messages, tasks, or a single calendar event in the calendar. This may be a single-item list if only one item is selected, or it can be a folder or text if text has been selected in a message or note window. Also, there might be no selection, which is rare but possible.
Before running this script, you need to select one or more contacts in the Address Book or in a custom view. The script checks the class of
item 1
of the selection to make sure that it is in fact a contact object. If there is no
item 1
(empty selection) or no selection, the
on error
block catches it. If the class of
item 1
is not a contact object, an error is invoked so
on error
catches it again, a beep and dialog box appear, and the script quits. The return command you see, which would quit the script, is actually never met. This is because in recent versions of Mac OS X, the Cancel button, which is the only button in the display dialog box, automatically causes an
error number -128
that quits the script.
Next, there is an inner
repeat 1 times
block inside the outer
repeat
block. This allows the script to skip an item (exit repeat) if its class is not the contact class. (You might have selected numerous kinds of items in a mixed custom view in the Projects area of Entourage.) Without the inner
repeat 1 times
block,
exit repeat
would just quit everything: the
repeat 1 times
substitutes for a
Next Repeat
which AppleScript does not have. (There are other ways to structure the script that still make it possible but it requires deeper nesting of
if
blocks.)
Most of the rest of the script is concerned with tracking down something to use as a name if the contact has no name. There is no
name
property of the contact class in the dictionary. But as an element of the application, a contact can be specified "by name," and the developers have implemented this
name
to point to the display name property of the contact class, as a synonym. The display name in turn consists of the concatenation of the first name and last name properties — though it is not documented — with an intermediate space between them if both first name and last name are not empty (otherwise no space).
The contact class has a display name property, because it is actually a subclass of the address class. So it also has an address property, even though it can have many e-mail addresses as elements. The address property points to the default email address property, or
""
if none.
If a contact has no first name and no last name, the Address Book displays the nickname, company, default e-mail address, or default IM address in the Name column, looking for text in that order. That's also what the script looks for, and it stops looking when it finds one of those. If none of those fields is filled, it's probably a rogue contact, and the script just moves on to the next selected contact, using the
exit repeat
referred to above.
Now it sets the flagged property of the contact object to true, which places a red flag in a column in the Address Book, and then makes a new task using "Flagged Contact: " plus the contact name as the name of the task,
today
as the due date, and the modified
now
(the next hour) as the remind date and time (reminder). In passing, without even needing separate lines, it sets the task's category to the contact's category (if any), which requires the explicit get. It does the same for the project list (that is, projects) property.
Finally, the script links the task to the contact and opens the task, that is, its window. This is precisely why you set a variable
theTask
when making it, to be able to follow up with the two final commands to link and open it. You can then adjust the due date and reminder time if you want.
If you think you might use this script in the future, save it to the Entourage Script Menu Items folder and add a keyboard shortcut such CONTROL+⌘+C to the end of its name.


