Address Book Scripts

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

  1. 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).

  2. 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

Hello.

Thanks a lot for sharing.

Best Regards

McUsr

Alan,

Thanks for posting what look to be very useful scripts. I’ve been looking recently for AppleScripts for Address Book and came across yours today.

I’m running Snow Leopard 10.6.4 and am seeing errors when I run the scripts from within the Script Editor. In the case of “Copy Address and Phones”, I see this:

If I run it after compiling, nothing is copied to the clipboard. I’m seeing similar errors in the other scripts. Does MP Replace have issues running on SL?

Thanks,

Des Dougan

Model: iMac
AppleScript: 2.1.2
Browser: Firefox 3.6
Operating System: Mac OS X (10.6)