This is a long post, sorry.
I have been wanting to post somewhere my scripts for managing Address Book. I have been using them since about OS X 10.3 days, and they have made it possible to use Address Book as if it was a sophisticated mailing database. (Thank you, AppleScript).
I follow the following rules
-
I used single word tags to put addresses in groups. I use kFriend for friends, kFamily for family, kFamilySmith for the Smith side of my family, etc. Then I can use smart folders (“Note contains kFamily”) to see all my family members–note that this will include all the Smiths).
-
In order to deal with people with 2 or more addresses, I have a constant “kPreferWork”, “kPreferHome” or “kPreferOther” in the notes field. You must add this constant to any contact with 2 or more addresses.
I then use these scripts. Select a bunch of contacts, run the Add String to Note End script and, voila, all these contacts are ready to be put into a smart group based on a string in the note. Select contacts in that group, and choose the Delete String from Note script, and now they are deleted from the smart group.
Of course you can create and delete the smart groups without any problems. The strings are still there, so you can recreate the smart group any time you want.
I also use these scripts to paste name + address into letters and envelopes, and to make tab-delimited files (easily converted to spread sheets or databases) for bulk mail or bulk email blasts.
I manage an Address Book with about 2,500 entries easily with this, and I suspect it would scale to at least 10,000 entries if needed.
===
To use these scripts enter each one into AppleScript Editor and save as Applications. Then place the compiled apps in ~/Library/Scripts/Applications/Address Book. You need to download one Scripting Addition and install it. It would be easy to rewrite these to avoid the Scripting Addition, but I have never felt the need to do so.
Brief summaries of the scripts are followed by the scripts themselves.
Copy Address
A 3 to 5 line Address (with formatting stripped) ready for pasting into a word processing document or envelope
Copy Address and Phones
Copy address + other contact info. I then paste into an email when I don’t want to send a vCard, or want to proof the contact info before I send it
Add String to Note End
Add String to Note Beginning
Add a string to end/beginning of all selected Address Book Cards. I use the first part of the note for any notes to myself (“met at conference”), then follow with a new line and any constants that I use to categorize them. So I always use the Add String to Note End script.
Copy Address as Family
Tries to copy the address as “John Smith and Helen Jones”. Not perfect.
Set kCountry
Puts “kCountry=…” in the notes field. Makes it easier to create smart folders that are country-based. (I couldn’t figure this out in AddressBook).
I put the following scripts inside a folder inside the Address Book scripts folder
Export Addresses as tab separated
Up to five columns, which can be easily used for a mailmerge on my home printer
Export Addressesfor mailing list
Keeps city/state/zip/country in separate columns so better if you are going to be sorting for a drop shipment
Export Names and emails
Used when you need to upload a list for an email blast
Now the scripts
Copy Address
--Most of this is copied out of the script "Export Addresses as tab separated"
--It is probably unnecessarily baroque, but we are at least using debugged code.
--
--Note the following:
-- If there are > 1 addresses, then you need to use the "kPreferHome", "kPreferWork" or "kPreferOther"
-- flags in the Note field. It is recommended that if, eg, "kPreferHome" is selected, then
-- there is only 1 "Home" address
--
-- If this is set up as a company, then we try to make it Attn: any person in the
-- first name/last name fields.
--
-- The job title etc fields are only used if this is a work address
--
set newline to ASCII character 10
set oldDelims to AppleScript's text item delimiters
try
tell application "Address Book"
set thePeople to get selection
set nPersons to count of thePeople
set theText to ""
repeat with personCtr from 1 to nPersons
if personCtr is not 1 then set theText to theText & "--" & return
set thePerson to item personCtr of thePeople
tell thePerson
set theNote to note
if theNote is missing value then set theNote to ""
set isCompany to company
set theName to ""
if name is not missing value then
if isCompany then
set theName to ""
if title is not missing value then
set theName to title
end if
if first name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & first name
end if
if last name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & last name
end if
if suffix is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & suffix
end if
else
set theName to name
end if
end if
set theJobTitle to ""
if job title is not missing value then
set theJobTitle to job title
end if
set theDept to ""
if department is not missing value then
set theDept to department
end if
set theOrg to ""
if organization is not missing value then
set theOrg to organization
end if
set jobTitleLine to ""
if theJobTitle is not "" then
set jobTitleLine to theJobTitle
end if
if theDept is not "" then
if jobTitleLine is not "" then set jobTitleLine to jobTitleLine & ", "
set jobTitleLine to jobTitleLine & theDept
end if
if theOrg is not "" then
if jobTitleLine is not "" then
if theDept is not "" then
set jobTitleLine to jobTitleLine & " - "
else
set jobTitleLine to jobTitleLine & ", "
end if
end if
set jobTitleLine to jobTitleLine & theOrg
end if
set theAddresses to addresses
end tell
set prefAddress to null
if (count of theAddresses) > 1 then
repeat with addrCtr from 1 to count of theAddresses
set anAddress to item addrCtr of theAddresses
if (((offset of "kPreferWork" in theNote) > 0) and (label of anAddress is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (label of anAddress is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (label of anAddress is "other")) then
set prefAddress to anAddress
exit repeat
end if
end repeat
else if (count of theAddresses) = 1 then
set prefAddress to item 1 of theAddresses
end if
set theCity to ""
set theState to ""
set theZip to ""
set theCountry to ""
set isWorkAddress to false
set streetlines to null
if prefAddress is null then
if (count of theAddresses) > 1 then
tell thePerson
if company then
set errorName to organization
else
set errorName to name
end if
end tell
if errorName is missing value then set errorName to "MISSING"
display dialog "The person " & errorName & " has more than 1 address. Please mark one of them as the preferred address by putting" & ¬
"\"kPreferHome\", \"kPreferWork\", or \"kPreferOther\" in the note field." & return & "Operation will continue without an address for this person."
end if
else
tell prefAddress
set isWorkAddress to label is "work"
if street is not missing value then
set streetlines to street
-- bug introduced in AddressBook for Mac OS X 10.5 Leopard
-- doesn't pass the command out, instead raises an errror
-- yet again, Apple moves backwards
tell me to set streetlines to MP Replace return using newline in string streetlines
set AppleScript's text item delimiters to {newline}
set streetlines to text items of streetlines
end if
if city is not missing value then
set theCity to city
end if
if state is not missing value then
set theState to state
end if
if zip is not missing value then
set theZip to zip
end if
if country is not missing value then
set theCountry to country
end if
end tell
end if
set cityStateLine to ""
if theCity is not "" then set cityStateLine to theCity
if theState is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & ", "
set cityStateLine to cityStateLine & theState
end if
if theZip is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & " "
set cityStateLine to cityStateLine & theZip
end if
set theLines to {}
if isCompany then
if jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
if theName is not "" then
set theLines to theLines & ("Attn: " & theName)
end if
else
if theName is not "" then
set theLines to theLines & theName
end if
if isWorkAddress and jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
end if
repeat with streetCtr from 1 to count of streetlines
set theLines to theLines & item streetCtr of streetlines
end repeat
if cityStateLine is not "" then
set theLines to theLines & cityStateLine
end if
if theCountry is not "" then
set theLines to theLines & theCountry
end if
set cleanLines to {}
repeat with lineCtr from 1 to count of theLines
set aLine to item lineCtr of theLines
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
set cleanLines to cleanLines & aLine
end repeat
repeat with lineCtr from 1 to count of cleanLines
set theText to theText & (item lineCtr of cleanLines as text) & return
end repeat
end repeat
get theText as text
get result as record
get «class ktxt» of result
set the clipboard to result
end tell
on error
set AppleScript's text item delimiters to oldDelims
beep
end try
set AppleScript's text item delimiters to oldDelims
Copy Address and Phones
--Most of this is copied out of the script "Export Addresses as tab separated"
--It is probably unnecessarily baroque, but we are at least using debugged code.
--
--Note the following:
--
-- If this is set up as a company, then we try to make it Attn: any person in the
-- first name/last name fields.
--
-- The job title etc fields are only used if this is a work address
--
set newline to ASCII character 10
set oldDelims to AppleScript's text item delimiters
try
tell application "Address Book"
set thePeople to get selection
set nPersons to count of thePeople
set theText to ""
repeat with personCtr from 1 to nPersons
if personCtr is not 1 then set theText to theText & "--" & return
set thePerson to item personCtr of thePeople
tell thePerson
set theNote to note
if theNote is missing value then set theNote to ""
set isCompany to company
set theName to ""
if name is not missing value then
if isCompany then
set theName to ""
if title is not missing value then
set theName to title
end if
if first name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & first name
end if
if last name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & last name
end if
if suffix is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & suffix
end if
else
set theName to name
end if
end if
set theJobTitle to ""
if job title is not missing value then
set theJobTitle to job title
end if
set theDept to ""
if department is not missing value then
set theDept to department
end if
set theOrg to ""
if organization is not missing value then
set theOrg to organization
end if
set jobTitleLine to ""
if theJobTitle is not "" then
set jobTitleLine to theJobTitle
end if
if theDept is not "" then
if jobTitleLine is not "" then set jobTitleLine to jobTitleLine & ", "
set jobTitleLine to jobTitleLine & theDept
end if
if theOrg is not "" then
if jobTitleLine is not "" then
if theDept is not "" then
set jobTitleLine to jobTitleLine & " - "
else
set jobTitleLine to jobTitleLine & ", "
end if
end if
set jobTitleLine to jobTitleLine & theOrg
end if
set theAddresses to addresses
end tell
if (count of theAddresses) is 0 then
if theName is not "" then
set aLine to theName
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
set theText to (theText & aLine as text) & return
end if
else
repeat with addrCtr from 1 to count of theAddresses
set theIsPreferred to ""
set theCity to ""
set theState to ""
set theZip to ""
set theCountry to ""
set theLabel to ""
set isWorkAddress to false
set streetlines to null
set theAddress to item addrCtr of theAddresses
tell theAddress
if label is not missing value then
set theLabel to label
end if
set isWorkAddress to label is "work"
if street is not missing value then
set streetlines to street
tell me to set streetlines to MP Replace return using newline in string streetlines
set AppleScript's text item delimiters to {newline}
set streetlines to text items of streetlines
end if
if city is not missing value then
set theCity to city
end if
if state is not missing value then
set theState to state
end if
if zip is not missing value then
set theZip to zip
end if
if country is not missing value then
set theCountry to country
end if
end tell
set cityStateLine to ""
if theCity is not "" then set cityStateLine to theCity
if theState is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & ", "
set cityStateLine to cityStateLine & theState
end if
if theZip is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & " "
set cityStateLine to cityStateLine & theZip
end if
if ((count of theAddresses) > 1 and ¬
(((offset of "kPreferWork" in theNote) > 0) and (theLabel is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (theLabel is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (theLabel is "other"))) then
set theIsPreferred to " (Preferred)"
end if
set theLines to {}
if isCompany then
if jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
if theName is not "" then
set theLines to theLines & ("Attn: " & theName)
end if
else
if theName is not "" then
set theLines to theLines & theName
end if
if isWorkAddress and jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
end if
repeat with streetCtr from 1 to count of streetlines
set theLines to theLines & item streetCtr of streetlines
end repeat
if cityStateLine is not "" then
set theLines to theLines & cityStateLine
end if
if theCountry is not "" then
set theLines to theLines & theCountry
end if
set cleanLines to {}
repeat with lineCtr from 1 to count of theLines
set aLine to item lineCtr of theLines
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
set cleanLines to cleanLines & aLine
end repeat
if (addrCtr is not 1) then
set theText to theText & return
end if
if ((count of theAddresses) is greater than 1 and theLabel is not "") then
set theText to theText & theLabel & theIsPreferred & ":" & return
end if
repeat with lineCtr from 1 to count of cleanLines
set theText to theText & (item lineCtr of cleanLines as text) & return
end repeat
end repeat
end if
set thePhones to phones of thePerson
repeat with phoneCtr from 1 to count of thePhones
if phoneCtr is 1 then
set theText to theText & return
end if
set thePhone to phone phoneCtr of thePerson
set theText to theText & label of thePhone & ": " & value of thePhone & return
end repeat
set theEmails to emails of thePerson
repeat with emailCtr from 1 to count of theEmails
if emailCtr is 1 then
set theText to theText & return
end if
set theEmail to email emailCtr of thePerson
set theText to theText & label of theEmail & ": " & value of theEmail & return
end repeat
end repeat
get theText as text
get result as record
get «class ktxt» of result
set the clipboard to result
end tell
on error
set AppleScript's text item delimiters to oldDelims
beep
end try
set AppleScript's text item delimiters to oldDelims
Add String to Note End
--
-- This script was written by Alan Harper.
-- Questions can be directed to alan@alanharper.com
-- Feel free to modify the script, but if you do, please remove my contact information above
--
-- This script purports to add a string to the end of the "note" field in AddressBook
-- You need to install MacPackToolbox <http://osaxen.com/files/macpacktoolbox1.4.html> first
--
property theString : ""
set newline to ASCII character 10
tell application "Address Book"
try
set thePeople to selection
set theCount to count of thePeople
if theCount > 0 then
set theDialogReply to display dialog ¬
"What string to add to selected addresses at end?" default answer theString
set theString to text returned of theDialogReply
repeat with ctr from 1 to theCount
set theId to id of item ctr of thePeople
set theNote to note of item ctr of thePeople
if theNote is missing value then set theNote to ""
set oldNote to theNote
tell me to set theNote to MP Replace theString using "" in string theNote
repeat while length of theNote > 1 and (item 1 of theNote is " " or item 1 of theNote is return or item 1 of theNote is newline)
set theNote to items 2 thru -1 of theNote as text
end repeat
repeat while length of theNote > 1 and (last item of theNote is " " or last item of theNote is return or last item of theNote is newline)
set theNote to items 1 thru -2 of theNote as text
end repeat
set theNote to theNote & newline & theString
if (theNote ≠oldNote) then
set note of (person id theId) to theNote
save
end if
end repeat
end if
on error
beep
end try
end tell
Add String to Note Beginning
--
-- This script was written by Alan Harper.
-- Questions can be directed to alan@alanharper.com
-- Feel free to modify the script, but if you do, please remove my contact information above
--
-- This script purports to add a string to the beginning of the "note" field in AddressBook
-- You need to install MacPackToolbox <http://osaxen.com/files/macpacktoolbox1.4.html> first
--
property theString : ""
set newline to ASCII character 10
tell application "Address Book"
try
set thePeople to selection
set theCount to count of thePeople
if theCount > 0 then
set theDialogReply to display dialog ¬
"What string to add to selected addresses at beginning?" default answer theString
set theString to text returned of theDialogReply
repeat with ctr from 1 to theCount
set theId to id of item ctr of thePeople
set theNote to note of item ctr of thePeople
if theNote is missing value then set theNote to ""
set oldNote to theNote
tell me to set theNote to MP Replace theString using "" in string theNote
repeat while length of theNote > 1 and (item 1 of theNote is " " or item 1 of theNote is return or item 1 of theNote is newline)
set theNote to items 2 thru -1 of theNote as text
end repeat
repeat while length of theNote > 1 and (last item of theNote is " " or last item of theNote is return or last item of theNote is newline)
set theNote to items 1 thru -2 of theNote as text
end repeat
set theNote to (theString & newline & theNote)
if (theNote ≠oldNote) then
set note of (person id theId) to theNote
tell application "Address Book" to save
end if
end repeat
end if
on error
beep
end try
end tell
Remove String from Note
--
-- This script was written by Alan Harper.
-- Questions can be directed to alan@alanharper.com
-- Feel free to modify the script, but if you do, please remove my contact information above
--
-- This script purports to remove a string from the "note" field in AddressBook
-- You need to install MacPackToolbox <http://osaxen.com/files/macpacktoolbox1.4.html> first
--
property theString : ""
set newline to ASCII character 10
tell application "Address Book"
try
set thePeople to selection
set theCount to count of thePeople
if theCount > 0 then
set theDialogReply to display dialog ¬
"What string to remove from selected addresses?" default answer theString
set theString to text returned of theDialogReply
repeat with ctr from 1 to theCount
set theId to id of item ctr of thePeople
set theNote to note of item ctr of thePeople
if theNote is missing value then set theNote to ""
set oldNote to theNote
tell me to set theNote to MP Replace theString using "" in string theNote
repeat while length of theNote > 1 and (item 1 of theNote is " " or item 1 of theNote is return or item 1 of theNote is newline)
set theNote to items 2 thru -1 of theNote as text
end repeat
repeat while length of theNote > 1 and (last item of theNote is " " or last item of theNote is return or last item of theNote is newline)
set theNote to items 1 thru -2 of theNote as text
end repeat
if (theNote ≠oldNote) then
set note of (person id theId) to theNote
save
end if
end repeat
end if
on error
beep
end try
end tell
Copy Address as Family
--Most of this is copied out of the script "1 Copy Address"
--It is probably unnecessarily baroque, but we are at least using debugged code.
--
--Note the following:
-- If there are > 1 addresses, then you need to use the "kPreferHome", "kPreferWork" or "kPreferOther"
-- flags in the Note field. It is recommended that if, eg, "kPreferHome" is selected, then
-- there is only 1 "Home" address
--
-- If this is set up as a company, then we try to make it Attn: any person in the
-- first name/last name fields.
--
-- The job title etc fields are only used if this is a work address
--
set newline to ASCII character 10
set oldDelims to AppleScript's text item delimiters
try
tell application "Address Book"
set thePeople to get selection
set nPersons to count of thePeople
set theText to ""
repeat with personCtr from 1 to nPersons
if personCtr is not 1 then set theText to theText & "--" & return
set thePerson to item personCtr of thePeople
tell thePerson
set theNote to note
if theNote is missing value then set theNote to ""
set isCompany to company
set theName to ""
set theSO to ""
set theJobTitle to ""
if job title is not missing value then
set theJobTitle to job title
end if
set theDept to ""
if department is not missing value then
set theDept to department
end if
set theOrg to ""
if organization is not missing value then
set theOrg to organization
end if
set jobTitleLine to ""
if theJobTitle is not "" then
set jobTitleLine to theJobTitle
end if
if theDept is not "" then
if jobTitleLine is not "" then set jobTitleLine to jobTitleLine & ", "
set jobTitleLine to jobTitleLine & theDept
end if
if theOrg is not "" then
if jobTitleLine is not "" then
if theDept is not "" then
set jobTitleLine to jobTitleLine & " - "
else
set jobTitleLine to jobTitleLine & ", "
end if
end if
set jobTitleLine to jobTitleLine & theOrg
end if
set theRelatedNames to related names
repeat with relatedNamesCtr from 1 to count of theRelatedNames
set theRelatedName to item relatedNamesCtr of theRelatedNames
if label of theRelatedName is "spouse" or label of theRelatedName is "partner" then
set theSO to value of theRelatedName
end if
end repeat
set AppleScript's text item delimiters to " "
set theSOWordCount to 0
if theSO is not "" then set theSOWordCount to count of text items of theSO
if name is not missing value then
if isCompany then
set theName to ""
if title is not missing value then
set theName to title
end if
if first name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & first name
if (theSOWordCount is 1) then
set theName to theName & " and " & theSO
end if
end if
if last name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & last name
end if
if suffix is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & suffix
end if
if theSOWordCount is greater than 1 then
set theName to theName & " and " & theSO
end if
else
if first name is not missing value then set theName to theName & first name
if theSOWordCount is 1 then set theName to theName & " and " & theSO
if last name is not missing value then set theName to theName & " " & last name
if theSOWordCount is greater than 1 then set theName to theName & " and " & theSO
end if
end if
set theAddresses to addresses
end tell
set prefAddress to null
if (count of theAddresses) > 1 then
repeat with addrCtr from 1 to count of theAddresses
set anAddress to item addrCtr of theAddresses
if (((offset of "kPreferWork" in theNote) > 0) and (label of anAddress is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (label of anAddress is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (label of anAddress is "other")) then
set prefAddress to anAddress
exit repeat
end if
end repeat
else if (count of theAddresses) = 1 then
set prefAddress to item 1 of theAddresses
end if
set theCity to ""
set theState to ""
set theZip to ""
set theCountry to ""
set isWorkAddress to false
set streetlines to null
if prefAddress is null then
if (count of theAddresses) > 1 then
tell thePerson
if company then
set errorName to organization
else
set errorName to name
end if
end tell
if errorName is missing value then set errorName to "MISSING"
display dialog "The person " & errorName & " has more than 1 address. Please mark one of them as the preferred address by putting" & ¬
"\"kPreferHome\", \"kPreferWork\", or \"kPreferOther\" in the note field." & return & "Operation will continue without an address for this person."
end if
else
tell prefAddress
set isWorkAddress to label is "work"
if street is not missing value then
set streetlines to street
tell me to set streetlines to MP Replace return using newline in string streetlines
set AppleScript's text item delimiters to {newline}
set streetlines to text items of streetlines
end if
if city is not missing value then
set theCity to city
end if
if state is not missing value then
set theState to state
end if
if zip is not missing value then
set theZip to zip
end if
if country is not missing value then
set theCountry to country
end if
end tell
end if
set cityStateLine to ""
if theCity is not "" then set cityStateLine to theCity
if theState is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & ", "
set cityStateLine to cityStateLine & theState
end if
if theZip is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & " "
set cityStateLine to cityStateLine & theZip
end if
set theLines to {}
if isCompany then
if jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
if theName is not "" then
set theLines to theLines & ("Attn: " & theName)
end if
else
if theName is not "" then
set theLines to theLines & theName
end if
if isWorkAddress and jobTitleLine is not "" then
set theLines to theLines & jobTitleLine
end if
end if
repeat with streetCtr from 1 to count of streetlines
set theLines to theLines & item streetCtr of streetlines
end repeat
if cityStateLine is not "" then
set theLines to theLines & cityStateLine
end if
if theCountry is not "" then
set theLines to theLines & theCountry
end if
set cleanLines to {}
repeat with lineCtr from 1 to count of theLines
set aLine to item lineCtr of theLines
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
set cleanLines to cleanLines & aLine
end repeat
repeat with lineCtr from 1 to count of cleanLines
set theText to theText & (item lineCtr of cleanLines as text) & return
end repeat
end repeat
get theText as text
get result as record
get «class ktxt» of result
set the clipboard to result
end tell
on error
set AppleScript's text item delimiters to oldDelims
end try
set AppleScript's text item delimiters to oldDelims
Set kCountry
--
-- This script was written by Alan Harper.
-- Questions can be directed to alan@alanharper.com
-- Feel free to modify the script, but if you do, please remove my contact information above
--
-- This script purports to add a string "kCountry=<country>" to the "note" field in AddressBook
-- and to remove this string if the country field is empty.
-- You might want to use this string if you want to have smart groups in address book that segregate on the country field
-- which currently is not possible to do directly.
--
-- Note that if there are multiple addresses in the contact, you need to use a string "kPreferHome", "kPreferWork"
-- or "kPreferOther" to discriminate which one you want. This is my hack, feel free to change it to your own :)
--
-- You need to install MacPackToolbox <http://osaxen.com/files/macpacktoolbox1.4.html> first
--
set newline to ASCII character 10
tell application "Address Book"
try
set thePeople to selection
set theCount to count of thePeople
if theCount > 0 then
repeat with ctr from 1 to theCount
set thePerson to item ctr of thePeople
tell thePerson
set theId to id
set theNote to note
if theNote is missing value then
set theNote to ""
end if
set oldNote to note
if oldNote is missing value then
set oldNote to ""
end if
set theAddresses to addresses
end tell
set prefAddress to null
if (count of theAddresses) > 1 then
repeat with addrCtr from 1 to count of theAddresses
set anAddress to item addrCtr of theAddresses
if (((offset of "kPreferWork" in theNote) > 0) and (label of anAddress is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (label of anAddress is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (label of anAddress is "other")) then
set prefAddress to anAddress
exit repeat
end if
end repeat
else if (count of theAddresses) = 1 then
set prefAddress to item 1 of theAddresses
end if
if prefAddress is null then
if (count of theAddresses) > 1 then
tell thePerson
if company then
set errorName to organization
else
set errorName to name
end if
end tell
if errorName is missing value then set errorName to "MISSING"
display dialog "The person " & errorName & " has more than 1 address. Please mark one of them as the preferred address by putting" & ¬
"\"kPreferHome\", \"kPreferWork\", or \"kPreferOther\" in the note field." & return & "Operation will continue without an address for this person."
end if
else
tell prefAddress
set theCountry to ""
if country is not missing value then
set theCountry to country
tell me to set theCountry to MP Replace " " using "_" in string theCountry
tell me to set theCountry to MP Replace tab using "_" in string theCountry
tell me to set theCountry to MP Replace return using "_" in string theCountry
tell me to set theCountry to MP Replace newline using "_" in string theCountry
end if
end tell
repeat
if length of theNote > 1 and item 1 of theNote is in {tab, space, return, newline} then
set theNote to items 2 thru -1 of theNote as text
else
exit repeat
end if
end repeat
set startOffset to offset of "kCountry=" in theNote
if startOffset > 0 then
set endOffset to startOffset + 1
repeat
if endOffset < length of theNote and item endOffset of theNote is not in {tab, space, return, newline} then
set endOffset to endOffset + 1
else
repeat
if endOffset < length of theNote and item endOffset of theNote is in {tab, space, return, newline} then
set endOffset to endOffset + 1
else
exit repeat
end if
end repeat
exit repeat
end if
end repeat
set part1 to ""
if startOffset > 1 then set part1 to characters 1 thru (startOffset - 1) of theNote as text
set part2 to ""
if endOffset < length of theNote then set part2 to characters (endOffset) thru (length of theNote) of theNote as text
if (length of part1 > 0) and (length of part2 > 0) and (item -1 of part1 is not in {tab, space, return, newline}) ¬
and (item 1 of part2 is not in {tab, space, return, newline}) then
set theNote to part1 & newline & part2
else
set theNote to part1 & part2
end if
end if
if theCountry is not "" then
if theNote is not "" then
set theNote to "kCountry=" & theCountry & newline & theNote
else
set theNote to "kCountry=" & theCountry
end if
end if
end if
if theNote ≠oldNote then
set note of (person id theId) to theNote
save
end if
end repeat
end if
on error
beep
end try
end tell
Export Addresses as Tab Separated
set newline to ASCII character 10
set oldDelims to AppleScript's text item delimiters
set theProgressIndicator to null
try
tell application "Address Book"
set thePeople to selection
set theCount to count of thePeople
display dialog "This script will write the " & theCount & " selected addresses as tab-separated values."
set maxAddrListCount to 0
set addrListList to {}
if theCount > 0 then
repeat with ctr from 1 to theCount
set thePerson to item ctr of thePeople
tell thePerson
--set theId to id
set theNote to note
if theNote is missing value then set theNote to ""
set isCompany to company
set theName to ""
if name is not missing value then
if isCompany then
set theName to ""
if title is not missing value then
set theName to title
end if
if first name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & first name
end if
if last name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & last name
end if
if suffix is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & suffix
end if
else
set theName to name
end if
end if
set theJobTitle to ""
if job title is not missing value then
set theJobTitle to job title
end if
set theDept to ""
if department is not missing value then
set theDept to department
end if
set theOrg to ""
if organization is not missing value then
set theOrg to organization
end if
set jobTitleLine to ""
if theJobTitle is not "" then
set jobTitleLine to theJobTitle
end if
if theDept is not "" then
if jobTitleLine is not "" then set jobTitleLine to jobTitleLine & ", "
set jobTitleLine to jobTitleLine & theDept
end if
if theOrg is not "" then
if jobTitleLine is not "" then
if theDept is not "" then
set jobTitleLine to jobTitleLine & " - "
else
set jobTitleLine to jobTitleLine & ", "
end if
end if
set jobTitleLine to jobTitleLine & theOrg
end if
set theAddresses to addresses
end tell
set prefAddress to null
if (count of theAddresses) > 1 then
repeat with addrCtr from 1 to count of theAddresses
set anAddress to item addrCtr of theAddresses
if (((offset of "kPreferWork" in theNote) > 0) and (label of anAddress is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (label of anAddress is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (label of anAddress is "other")) then
set prefAddress to anAddress
exit repeat
end if
end repeat
else if (count of theAddresses) = 1 then
set prefAddress to item 1 of theAddresses
end if
set theCity to ""
set theState to ""
set theZip to ""
set theCountry to ""
set isWorkAddress to false
set streetlines to null
if prefAddress is null then
if (count of theAddresses) > 1 then
tell thePerson
if company then
set errorName to organization
else
set errorName to name
end if
end tell
if errorName is missing value then set errorName to "MISSING"
display dialog "The person " & errorName & " has more than 1 address. Please mark one of them as the preferred address by putting" & ¬
"\"kPreferHome\", \"kPreferWork\", or \"kPreferOther\" in the note field." & return & "Operation will continue without an address for this person."
end if
else
tell prefAddress
set isWorkAddress to label is "work"
if street is not missing value then
set streetlines to street
tell me to set streetlines to MP Replace return using newline in string streetlines
set AppleScript's text item delimiters to {}
repeat while length of streetlines > 0 and item -1 of streetlines is newline
set streetlines to characters 1 thru -2 of streetlines as string
end repeat
set AppleScript's text item delimiters to {newline}
set streetlines to text items of streetlines
end if
if city is not missing value then
set theCity to city
end if
if state is not missing value then
set theState to state
end if
if zip is not missing value then
set theZip to zip
end if
if country is not missing value then
set theCountry to country
end if
end tell
end if
set cityStateLine to ""
if theCity is not "" then set cityStateLine to theCity
if theState is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & ", "
set cityStateLine to cityStateLine & theState
end if
if theZip is not "" then
if cityStateLine is not "" then set cityStateLine to cityStateLine & " "
set cityStateLine to cityStateLine & theZip
end if
--
-- Now fill out the lines of the address
--
set theAddrList to {}
if isCompany then
if jobTitleLine is not "" then
set theAddrList to theAddrList & jobTitleLine
end if
if theName is not "" then
set theAddrList to theAddrList & ("Attn: " & theName)
end if
else
if theName is not "" then
set theAddrList to theAddrList & theName
end if
if isWorkAddress and jobTitleLine is not "" then
set theAddrList to theAddrList & jobTitleLine
end if
end if
if streetlines ≠null then
repeat with streetCtr from 1 to count of streetlines
set theAddrList to theAddrList & item streetCtr of streetlines
end repeat
end if
if cityStateLine is not "" then
set theAddrList to theAddrList & cityStateLine
end if
if theCountry is not "" then
set theAddrList to theAddrList & theCountry
end if
set cleanAddrList to {}
set listCount to count of theAddrList
if listCount > maxAddrListCount then
set maxAddrListCount to listCount
end if
repeat with listCtr from 1 to listCount
set aLine to item listCtr of theAddrList
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
set cleanAddrList to cleanAddrList & aLine
end repeat
set addrListList to addrListList & {cleanAddrList}
end repeat
end if
end tell
set outputTable to ""
repeat with ctr from 1 to maxAddrListCount
if outputTable is not "" then
set outputTable to outputTable & tab
end if
set rowTitle to "line_" & ctr
set outputTable to outputTable & rowTitle
end repeat
repeat with ctr from 1 to theCount
set cleanAddrList to item ctr of addrListList
repeat with moreNullCtr from (length of cleanAddrList) + 1 to maxAddrListCount
set cleanAddrList to cleanAddrList & ""
end repeat
set AppleScript's text item delimiters to {tab}
set cleanLineText to cleanAddrList as text
set outputTable to outputTable & return & cleanLineText
end repeat
set theFileName to choose file name with prompt "Where should I write the tab-separated values?"
set theFileRefNum to open for access theFileName with write permission
try
set eof theFileRefNum to 0
write outputTable to theFileRefNum
on error
close access theFileRefNum
end try
close access theFileRefNum
on error theErrorText number theErrorNumber
set AppleScript's text item delimiters to oldDelims
end try
set AppleScript's text item delimiters to oldDelims
Export Addresses as Mailing List
global newline
global oldDelims
on cleanALine(aLine)
if length of aLine > 0 then
tell me to set aLine to MP Replace tab using " " in string aLine
tell me to set aLine to MP Replace return using "; " in string aLine
tell me to set aLine to MP Replace newline using "; " in string aLine
end if
return aLine
end cleanALine
set oldDelims to AppleScript's text item delimiters
set newline to ASCII character 10
try
tell application "Address Book"
set thePeople to selection
set theCount to count of thePeople
display dialog "This script will write the " & theCount & " selected addresses as tab-separated values."
set maxAddrListCount to 0
set addrListList to {}
if theCount > 0 then
repeat with ctr from 1 to theCount
set thePerson to item ctr of thePeople
tell thePerson
--set theId to id
set theNote to note
if theNote is missing value then set theNote to ""
set isCompany to company
set theName to ""
if name is not missing value then
if isCompany then
set theName to ""
if title is not missing value then
set theName to title
end if
if first name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & first name
end if
if last name is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & last name
end if
if suffix is not missing value then
if theName is not "" then set theName to theName & " "
set theName to theName & suffix
end if
else
set theName to name
end if
end if
set theJobTitle to ""
if job title is not missing value then
set theJobTitle to job title
end if
set theDept to ""
if department is not missing value then
set theDept to department
end if
set theOrg to ""
if organization is not missing value then
set theOrg to organization
end if
set jobTitleLine to ""
if theJobTitle is not "" then
set jobTitleLine to theJobTitle
end if
if theDept is not "" then
if jobTitleLine is not "" then set jobTitleLine to jobTitleLine & ", "
set jobTitleLine to jobTitleLine & theDept
end if
if theOrg is not "" then
if jobTitleLine is not "" then
if theDept is not "" then
set jobTitleLine to jobTitleLine & " - "
else
set jobTitleLine to jobTitleLine & ", "
end if
end if
set jobTitleLine to jobTitleLine & theOrg
end if
set theAddresses to addresses
end tell
set prefAddress to null
if (count of theAddresses) > 1 then
repeat with addrCtr from 1 to count of theAddresses
set anAddress to item addrCtr of theAddresses
if (((offset of "kPreferWork" in theNote) > 0) and (label of anAddress is "work")) or ¬
(((offset of "kPreferHome" in theNote) > 0) and (label of anAddress is "home")) or ¬
(((offset of "kPreferOther" in theNote) > 0) and (label of anAddress is "other")) then
set prefAddress to anAddress
exit repeat
end if
end repeat
else if (count of theAddresses) = 1 then
set prefAddress to item 1 of theAddresses
end if
set theCity to ""
set theState to ""
set theZip to ""
set theCountry to ""
set isWorkAddress to false
set streetlines to null
if prefAddress is null then
if (count of theAddresses) > 1 then
tell thePerson
if company then
set errorName to organization
else
set errorName to name
end if
end tell
if errorName is missing value then set errorName to "MISSING"
display dialog "The person " & errorName & " has more than 1 address. Please mark one of them as the preferred address by putting" & ¬
"\"kPreferHome\", \"kPreferWork\", or \"kPreferOther\" in the note field." & return & "Operation will continue without an address for this person."
end if
else
tell prefAddress
set isWorkAddress to label is "work"
if street is not missing value then
set streetlines to street
tell me to set streetlines to MP Replace return using newline in string streetlines
set AppleScript's text item delimiters to {}
repeat while length of streetlines > 0 and item -1 of streetlines is newline
set streetlines to characters 1 thru -2 of streetlines as string
end repeat
set AppleScript's text item delimiters to {newline}
set streetlines to text items of streetlines
end if
if city is not missing value then
set theCity to city
end if
if state is not missing value then
set theState to state
end if
if zip is not missing value then
set theZip to zip
end if
if country is not missing value then
set theCountry to country
end if
end tell
end if
--
-- Now fill out the lines of the address
--
set theAddrList to {}
if isCompany then
if jobTitleLine is not "" then
set theAddrList to theAddrList & jobTitleLine
end if
if theName is not "" then
set theAddrList to theAddrList & ("Attn: " & theName)
end if
else
if theName is not "" then
set theAddrList to theAddrList & theName
end if
if isWorkAddress and jobTitleLine is not "" then
set theAddrList to theAddrList & jobTitleLine
end if
end if
if streetlines ≠null then
repeat with streetCtr from 1 to count of streetlines
set theAddrList to theAddrList & item streetCtr of streetlines
end repeat
end if
if (count of theAddrList) > 4 then
set theAddrList to items 1 thru 4 of theAddrList
end if
if (count of theAddrList) < 4 then
set theAddrList to theAddrList & items 1 thru (4 - (count of theAddrList)) of {{}, {}, {}, {}}
end if
set cleanAddrList to {}
tell me
set cleanAddrList to cleanAddrList & {cleanALine(item 1 of theAddrList)}
set cleanAddrList to cleanAddrList & {cleanALine(item 2 of theAddrList)}
set cleanAddrList to cleanAddrList & {cleanALine(item 3 of theAddrList)}
set cleanAddrList to cleanAddrList & {cleanALine(item 4 of theAddrList)}
set cleanAddrList to cleanAddrList & {cleanALine(theCity)}
set cleanAddrList to cleanAddrList & {cleanALine(theState)}
set cleanAddrList to cleanAddrList & {cleanALine(theZip)}
set cleanAddrList to cleanAddrList & {cleanALine(theCountry)}
end tell
set addrListList to addrListList & {cleanAddrList}
end repeat
end if
end tell
set outputTable to "line 1" & tab & "line 2" & tab & "line 3" & tab & "line 4" & tab & "City" & tab & "State" & tab & "Zip" & tab & "Country"
repeat with ctr from 1 to theCount
set addrListItem to item ctr of addrListList
set AppleScript's text item delimiters to {tab}
set addrListItem to addrListItem as text
set outputTable to outputTable & return & addrListItem
end repeat
set theFileName to choose file name with prompt "Where should I write the tab-separated values?"
set theFileRefNum to open for access theFileName with write permission
try
set eof theFileRefNum to 0
write outputTable to theFileRefNum
on error
close access theFileRefNum
end try
close access theFileRefNum
on error theErrorText number theErrorNumber
set AppleScript's text item delimiters to oldDelims
end try
set AppleScript's text item delimiters to oldDelims
Export Names and Emails
set newline to ASCII character 10
set oldDelims to AppleScript's text item delimiters
try
tell application "Address Book"
set thePeople to selection
set theCount to count of thePeople
display dialog "This script will write the " & theCount & " selected addresses as tab-separated values."
set maxAddrListCount to 0
set outputString to ""
if theCount > 0 then
repeat with ctr from 1 to theCount
set thePerson to item ctr of thePeople
tell thePerson
set theFirstName to ""
set theLastName to ""
set theNote to ""
set theEmail to ""
if first name is not missing value then
set theFirstName to first name
end if
if last name is not missing value then
set theLastName to last name
end if
if note is not missing value then
set theNote to note
end if
if (count of emails) is greater than 0 then
repeat with emailCtr from 1 to count of emails
if theEmail is "" then
set theEmail to value of item emailCtr of emails
end if
if theNote contains "kPreferWork" and label of item emailCtr of emails is "work" then
set theEmail to value of item emailCtr of emails
end if
if theNote contains "kPreferHome" and label of item emailCtr of emails is "home" then
set theEmail to value of item emailCtr of emails
end if
if theNote contains "kPreferOther" and label of item emailCtr of emails is "other" then
set theEmail to value of item emailCtr of emails
end if
end repeat
end if
set theLine to theFirstName & " " & theLastName & " " & theEmail & "
"
set outputString to outputString & theLine
end tell
end repeat
end if
end tell
set theFileName to choose file name with prompt "Where should I write the tab-separated values?"
set theFileRefNum to open for access theFileName with write permission
try
set eof theFileRefNum to 0
write outputString to theFileRefNum
on error
close access theFileRefNum
end try
close access theFileRefNum
on error
set AppleScript's text item delimiters to oldDelims
end try
set AppleScript's text item delimiters to oldDelims