Address Book Contact Split

If Address Book contains contacts with two names (i.e. Mary & John) in the first name field, then they might need to be split if individual mailing labels are to be printed or separate individual details like birthdays are to be maintained.

Splitting one contact manually takes long enough - dealing with a large Address Book takes forever.

This script scans Address Book, identifies “double” first names and asks if they should be split. It leaves the original contact unchanged and inserts two new ones with the individual’s correct first name. New contacts contain addresses, 'phone numbers, email addresses and notes derived from the original contact.

The script is fully annotated so that the first name separator ( & ), the Address Book fields processed, etc. can be easily altered to localize it to your requirements…

display dialog "This script splits selected Address Book contacts containing two first names (i.e. Darren & Debbie)." & return & return & "It leaves the original contact unchanged and creates a new contact for each of the two first named persons." & return & return & "Addresses, 'phone numbers, email addresses and notes present in the original contact are reproduced in the two new contacts" buttons {"Great, proceed", "Cancel"} with icon 1

-- Opening dialogue

tell application "Address Book"
	activate
	
	-- Open Address Book
	
	set myPeople to (every person whose company is not true and first name contains " & ")
	
	-- Find all personal (not company) contacts with two first names
	
	set myCount to 0
	
	-- Initialise count of number of split contacts
	
	display dialog "Patience!" & return & return & "There are " & (count of myPeople) & " contacts to review..." with icon 1
	
	-- Display the number of contacts to be searched
	
	repeat with i from 1 to count of myPeople
		
		-- Set up repeat loop to process selected contacts
		
		set firstname to (first name of item i of myPeople)
		if firstname contains "&" then
			
			-- Identify next contact with "&" in first name
			
			display dialog "The contact " & firstname & " " & (last name of item i of myPeople) & " contains two people..." & return & return & "Do you want to split them?" buttons {"Yes, split this contact", "No, find next contact", "Stop"} default button 1 with icon 1
			if (button returned of result) is "Yes, split this contact" then
				
				-- Ask if this contact should be split
				
				set AppleScript's text item delimiters to " & "
				
				-- Set delimiters to first name separator used in Address Book
				
				set nameText to firstname's text items
				
				-- Get separated first names
				
				set AppleScript's text item delimiters to {""}
				
				-- Restore delimiters to default value
				
				set splitFirstName to (item 1 of nameText)
				set splitSecondName to (item 2 of nameText)
				
				-- Separate out first names of current contact
				
				repeat with contactCount from 1 to 2
					
					-- Initialise contact creation loop
					
					if contactCount = 1 then
						
						set newPerson to make new person with properties {last name:(word -1 of item i of myPeople)}
						
						-- Create first blank contact
						
						tell newPerson
							set first name to (splitFirstName as text)
							set last name to (last name of item i of myPeople)
						end tell
						
						-- Insert first part of split first name and original last name in first blank contact
						
					else
						set newPerson to make new person with properties {last name:(word -1 of item i of myPeople)}
						
						-- Create second blank contact
						
						tell newPerson
							set first name to (splitSecondName as text)
							set last name to (last name of item i of myPeople)
						end tell
						
						-- Insert second part of split first name and original last name in second blank contact
						
					end if
					
					set theNote to note of (item i of myPeople)
					
					--Find note from original contact
					
					tell newPerson
						set note to theNote
					end tell
					
					-- Insert note in new contact
					
					set theAddresses to addresses of (item i of myPeople)
					
					-- Find all addresses from original contact
					
					repeat with thisAddress in theAddresses
						set thisStreet to street of thisAddress
						set thisCity to city of thisAddress
						set thisState to state of thisAddress
						set thisZip to zip of thisAddress
						set thisCountry to country of thisAddress
						set thisLabel to label of thisAddress
						
						-- Find individual properties of each address
						
						tell newPerson
							make new address at end of addresses with properties {street:thisStreet, city:thisCity, state:thisState, zip:thisZip, country:thisCountry, label:thisLabel}
						end tell
						
						-- Insert addresses in new contact
						
					end repeat
					
					repeat with thisPhone in phones of (item i of myPeople)
						
						-- Find all 'phones from original contact
						
						set thisNum to value of thisPhone
						set thisLabel to label of thisPhone
						
						-- Find individual properties of each 'phone
						
						tell newPerson
							make new phone at end of phones with properties {value:thisNum, label:thisLabel}
						end tell
						
						-- Insert 'phones in new contact
						
					end repeat
					
					repeat with thisEmail in emails of (item i of myPeople)
						
						-- Find all email addresses from original contact
						
						set thisEmailAddress to value of thisEmail
						set thisLabel to label of thisEmail
						
						-- Find individual properties of each email address
						
						tell newPerson
							make new email at end of emails with properties {value:thisEmailAddress, label:thisLabel}
						end tell
						
						-- Insert email addresses in new contact
						
					end repeat
				end repeat
				
				set myCount to (myCount + 1)
				
				-- Increment count of split contacts
				
			else
				if (button returned of result) is "Stop" then
					save addressbook
					
					-- Update address book if script is interrupted
					
					display dialog "There are another " & ((count of myPeople) - i) & " contacts to process..." & return & return & "Are you sure you want to cancel?" buttons {"No, continue splitting", "Cancel"} default button 1 with icon 2
					
					-- Ask if script is to be terminated
					
				end if
			end if
		end if
	end repeat
	
	save addressbook
	
	-- Update address book at completion of scan
	
end tell

tell application "Address Book"
	display dialog (myCount as text) & " contact(s) containing two names divided..." buttons {"Thanks..."} with icon 1
	
	-- Closing dialogue
	
	quit application "Address Book"
	
	-- Close addreess book
	
end tell

Enjoy…

Model: iMac
AppleScript: 2.2.1
Browser: Safari 4.0.3
Operating System: Mac OS X (10.5)

Hi,

I just found this (while looking for something else, as it happens :confused: ). Presumably some bits would need changing to comply with AS under Lion?

I get this error:

,

and this section of the script is highlighted:

What would I need to change to make it work in Lion?

And related . is there a way I could edit the script so that each of the newly created pairs of contacts has the first name of the other as “spouse”?

Thanks.

Model: MBP 13"
AppleScript: 2.4.2
Browser: Safari 534.55.3
Operating System: Mac OS X (10.7)

Hi, Lance.

For some reason, the script’s trying to get the last ‘word’ of a ‘person’ instead of their ‘last name’.

I’ve presumed to tidy it up a bit by improving the code in a few places and putting the comments above the code to which they refer. The version below works in Snow Leopard. I’ll think about your ‘spouse’ problem as a separate exercise.

-- Opening dialogue
display dialog "This script splits selected Address Book contacts containing two first names (i.e. Darren & Debbie)." & return & return & "It leaves the original contact unchanged and creates a new contact for each of the two first named persons." & return & return & "Addresses, 'phone numbers, email addresses and notes present in the original contact are reproduced in the two new contacts" buttons {"Great, proceed", "Cancel"} with icon 1

tell application "Address Book"
	-- Open Address Book
	activate
	
	-- Find all personal (not company) contacts with two first names
	set myPeople to (every person whose company is false and first name contains " & ")
	set originalCount to (count myPeople)
	
	-- Initialise count of number of split contacts
	set myCount to 0
	
	-- Display the number of contacts to be searched
	display dialog "Patience!" & return & return & "There are " & originalCount & " contacts to review..." with icon 1
	
	-- Set up repeat loop to process selected contacts
	repeat with i from 1 to originalCount
		
		-- Get next contact with " & " in first name
		set thisContact to item i of myPeople
		set {name:fullname, first name:firstname, last name:lastname} to thisContact
		
		-- Ask if this contact should be split
		set buttonReturned to button returned of (display dialog "The contact " & fullname & " contains two people..." & return & return & "Do you want to split them?" buttons {"Yes, split this contact", "No, find next contact", "Stop"} default button 1 with icon 1)
		
		if (buttonReturned is "Yes, split this contact") then
			
			-- Set delimiters to first-name separator used in Address Book (assumed to be " & ")
			set AppleScript's text item delimiters to " & "
			
			-- Get separated first names
			set splitNames to firstname's text items
			
			-- Restore delimiters to default value
			set AppleScript's text item delimiters to {""}
			
			-- Initialise contact creation loop
			repeat with contactCount from 1 to 2
				
				-- Create new contact
				set newPerson to (make new person with properties {first name:item contactCount of splitNames, last name:lastname})
				
				-- Find note from original contact
				set theNote to note of thisContact
				-- Insert note in new contact
				set newPerson's note to theNote
				
				-- Find all addresses from original contact
				set theAddresses to addresses of thisContact
				
				repeat with thisAddress in theAddresses
					-- Find individual properties of each address
					set thisStreet to street of thisAddress
					set thisCity to city of thisAddress
					set thisState to state of thisAddress
					set thisZip to zip of thisAddress
					set thisCountry to country of thisAddress
					set thisLabel to label of thisAddress
					
					-- Insert addresses in new contact
					tell newPerson
						make new address at end of addresses with properties {street:thisStreet, city:thisCity, state:thisState, zip:thisZip, country:thisCountry, label:thisLabel}
					end tell
				end repeat
				
				-- Find all 'phones from original contact
				set thePhones to phones of thisContact
				
				repeat with thisPhone in thePhones
					
					-- Find individual properties of each 'phone		
					set thisNum to value of thisPhone
					set thisLabel to label of thisPhone
					
					-- Insert 'phones in new contact
					tell newPerson
						make new phone at end of phones with properties {value:thisNum, label:thisLabel}
					end tell
					
				end repeat
				
				-- Find all email addresses from original contact
				set theEmails to emails of thisContact
				
				repeat with thisEmail in theEmails
					
					-- Find individual properties of each email address
					set thisEmailAddress to value of thisEmail
					set thisLabel to label of thisEmail
					
					-- Insert email addresses in new contact
					tell newPerson
						make new email at end of emails with properties {value:thisEmailAddress, label:thisLabel}
					end tell
					
				end repeat
			end repeat
			
			-- Increment count of split contacts
			set myCount to (myCount + 1)
						
		else if (buttonReturned is "Stop") then
			-- Update address book if script is interrupted
			save
			
			-- Ask if script is to be terminated
			set remainingCount to originalCount - i
			if (remainingCount > 0) then
				display dialog "There are another " & remainingCount & " contacts to process..." & return & return & "Are you sure you want to cancel?" buttons {"No, continue splitting", "Stop"} default button 1 with icon 2
				if (button returned of result is "Stop") then exit repeat
			end if
		end if
	end repeat
	
	-- Update address book at completion of scan
	save
	
	-- Closing dialogue
	display dialog (myCount as text) & " contact(s) containing two names divided..." buttons {"Thanks..."} with icon 1
	
	-- Close Address Book
	quit
	
end tell

Yes. Just insert this somewhere suitable after the creation of newPerson in the ‘repeat with contactCount from 1 to 2’ statement:


-- Make the other name from the split this one's spouse.
tell newPerson
	make new related name at end of related names with properties {value:item -contactCount of splitNames, label:"spouse"} -- NB. contactCount negative for the other of the two.
end tell

Hi Nigel,

Thanks so much for taking that trouble.

Good - It worked for me (including the spouse bit) in Lion, with no errors reported.

Bad (slightly) - I finished up with duplicates of every new contact - i.e. 2x2 (4) new contacts created from every existing couple contact. So had to delete the dupes.