Moving from Microsoft Office VBA to AppleScript:
MacTech's Guide to Making the Transition
Introduction
|
Table of Contents
Page Prev and Page Next buttons at bottom of the page.
|
April, 2007
Page 127
(get category of theContact), project list:¬
(get project list of theContact)}
link theTask to theContact
open theTask
end repeat
end repeat
end tell
The first section of the script prepares the times for the due date and reminder of the task to be created. It is always best to perform date manipulations outside application tell blocks if possible: otherwise you sometimes hit errors. (If you do, and can't extricate yourself from the tell block, try tell AppleScript to … That sometimes works.) As you may have learned, dates, along with lists, records and script objects only, and unlike all other data types in AppleScript, are mutable when variables are set to them. (The old AppleScript Language Guide refers to these four data types as "Data Sharing" types: I will refer to them as "mutable".)
Since we want two different dates (times) to be derived from the variable now which is set to the current time (current date), we need to copy, not set, the variable now to today. Otherwise any changes we make to today would also occur with now. (Most other programming languages have far more mutable types and objects than AppleScript does.)
now and today are date objects, meaning date-and-time. (Read up more on dates in an AppleScript book.) By setting the time of today to 0, we 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 our other date variable now we need to do some fancier date arithmetic. We are going to pre-set 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 some handy 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 you need them.
We use the operator div to get the whole-number integer part of the dividend of now's time when divided by hours (3600), i.e., the hour of the current time (e.g., 14 for 2:00 pm), 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 will automatically roll over to 0:00 of the next day, with the day and date advancing)
The next part of the script first gets the selection. As discussed in the first part of this chapter, selection can be a list (of items such as contacts, messages, tasks, also a single calendar event in the calendar) which may be a single-item list if only one item is selected, or it can be a folder, or it can be text if text has been selected in a message or note window. Or there might be no selection (rare but possible).
Before running this script you are meant 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 it is in fact a contact: 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 contact, an error is invoked so on error catches it again, a beep and dialog appear and the script quits. The return command you see, which would quit the script, is actually never met since now (since about OS 10.2 or so) the "Cancel" button, which is the only button in the display dialog, itself automatically causes a number -128 error that quits the script.
All being well, the script proceeds. You will notice again, as with several other scripts used as examples, that there is an inner repeat 1 times block inside the outer repeat block. That is to allow the script to skip an item (exit repeat) if its class is not contact. (You might have selected a number of different kinds of items in a Mixed custom view in the Projects area of Entourage.) Without the inner 1 times repeat block, exit repeat would just quit everything: the 1 times repeat 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. You may have noticed that there is actually no name property of contact 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 contact, as a synonym. The display name in turn – though it does not say so anywhere – consists of the concatenation of the first name and last name properties with an intermediate space between them if both first name and last name are not empty (otherwise no space).
Contact has a display name property because, surprisingly, contact is actually a subclass of the address class. (So it also has an address property too, even though it can have many email addresses as elements. address 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 in the "Name" column the nickname, company, default email address, or default IM address, looking (for text) in that order. So that's what the script looks for too, and 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, via that exit repeat referred to above.
Now it sets the flagged property of the contact to true, which will place a red flag in the next-to-leftmost 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; and the same for the project list (i.e., projects) property.
< Previous Page Next Page>
- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine