Extract a record from AddressBook

Is there a more efficient code to extract a record containing a given last name?


tell application "Address Book"
	activate
	set nbPersons to count of person
	set found to false
	repeat with i from 1 to nbPersons
		if last name of person i is "DUPOND" then
			set found to true
			exit repeat
		end if
	end repeat
	if found then
		get properties of person i
	end if
end tell

I tried to use whose


tell application "Address Book"
	activate
	get properties of person whose last name is "DUPOND"
end tell

but always got an error message.

Yvan KOENIG (VALLAURIS, France) vendredi 27 novembre 2009 13:31:55

Salu Yvan,

the result of the whose filter is a list, so try either


tell application "Address Book"
	activate
	get people whose last name is "DUPOND"
end tell

or

tell application "Address Book"
	activate
	get 1st person whose last name is "DUPOND"
end tell

to read or write property values of an element (like person) it’s not necessary to get the properties explicitly

Merci Stephan

Both scripts do the trick flawlessly.

It seems that I was tired to miss that.

Yvan KOENIG (VALLAURIS, France) vendredi 27 novembre 2009 17:34:24

With the response to my first question, I was able to write this script:


(*
properties
birth date (date) : The birth date of this person.
company (boolean) : Is the current record a company or a person.
department (Unicode text) : Department that this person works for.
first name (Unicode text) : The First name of this person.
home page (Unicode text) : The home page of this person.
image (TIFF picture) : Image for person.
job title (Unicode text) : The job title of this person.
last name (Unicode text) : The Last name of this person.
maiden name (Unicode text) : The Maiden name of this person.
middle name (Unicode text) : The Middle name of this person.
nickname (Unicode text) : The Nickname of this person.
note (Unicode text) : Notes for this person.
organization (Unicode text) : Organization that employs this person.
phonetic first name (Unicode text) : The phonetic version of the First name of this person.
phonetic last name (Unicode text) : The phonetic version of the Last name of this person.
phonetic middle name (Unicode text) : The Phonetic version of the Middle name of this person.
suffix (Unicode text) : The Suffix of this person.
title (Unicode text) : The title of this person..
*)
--set firstname to "FirstName"
set thelastname to "LastName"
set theCompany to true
set theStreet to "1234 last street"
set thePostalCode to "5678"
set theCity to "Azerty"
set theMailAddress to "address@address.com"

set theUrl to "http://www.qwerty.com"

tell application "Address Book"
	if not (exists person thelastname) then
		set the_person to (make new person with properties {last name:thelastname, company:theCompany})
		make new email at the end of the_person with properties {value:theMailAddress, label:"work"}
		make new address at the end of the_person with properties {street:theStreet, zip:thePostalCode, city:theCity, label:"work"}
		make new url at end of the_person with properties {value:theUrl, label:"url"}
	else
		(* here code to update the existing record *)
		set thePerson to get 1st person whose last name is thelastname
		
		try
			set oldMail to get email of thePerson
			set properties of oldMail to {value:"newMail@address.com"}
		on error errMsg number errnbr
			log errMsg
			make new email at the end of thePerson with properties {value:"newMail@address.com", label:"work"}
		end try
		
		try
			set oldUrl to get url of thePerson
			set properties of oldUrl to {"http://www.dvorak.com"}
		on error errMsg number errnbr
			log errMsg
			make new url at the end of thePerson with properties {value:"http://www.dvorak.com", label:"work"}
		end try
		
		try
			set theAddress to get address of thePerson
			set properties of theAddress to {street:"newStreet"}
		on error errMsg number errnbr
			log errMsg
			make new address at the end of thePerson with properties {street:"newStreet", zip:thePostalCode, city:theCity, label:"work"}
		end try
	end if
	save addressbook
end tell

It works well to create a new record but if a record with the same last name already exists, it doesn’t change the contents of email, url, address but it creates new items.

What am’I doing wrongly ?

Yvan KOENIG (VALLAURIS, France) dimanche 29 novembre 2009 21:01:27

Hi Yvan,

some notes:

you can specify a person by its (full) name, not the last name


set theName to "John Doe"

tell application "Address Book"
	if not (exists person theName) then
		set the_person to (make new person with properties {last name:thelastname, company:theCompany})
		tell the_person
			make new email at the end of emails with properties {value:theMailAddress, label:"work"}
			make new address at the end of addresses with properties {street:theStreet, zip:thePostalCode, city:theCity, label:"work"}
			make new url at end of urls with properties {value:theUrl, label:"url"}
		end tell
	else
		(* here code to update the existing record *)
		set thePerson to person theName
.

emails, urls, addresses (all plural) are lists of elements. To change a value you must specify the appropriate entry.

Hello Stephan

It seems that you read too quickly.

As is, my posted script behaves flawlessly to create a new record.

The problem is only when the record already exists and some datas must be changed.

It’s the code after the else which fails.

I want a code replacing :
a mail address by an other one
an URL by an other one
an address or a component of an address by an other one.

At this time it creates a new item which is not what is wanted.

Yvan KOENIG (VALLAURIS, France) lundi 30 novembre 2009 08:27:44

I read slowly and carefully. :wink:

For example you can’t get the value of email of a person, because emails is always a list of elements. Assuming urls, addresses and emails contains only one entry, try this


set theName to "John Doe"
set theCompany to true
set theStreet to "1234 last street"
set thePostalCode to "5678"
set theCity to "Azerty"
set theMailAddress to "address@address.com"

set theUrl to "http://www.qwerty.com"

tell application "Address Book"
	if not (exists person theName) then
		set the_person to (make new person with properties {last name:thelastname, company:theCompany})
		tell the_person
			make new email at the end of emails with properties {value:theMailAddress, label:"work"}
			make new address at the e[color=blue]nd of addresses with properties {street:theStreet, zip:thePostalCode, city:theCity, label:"work"}
			make new url at end of urls with properties {value:theUrl, label:"url"}
		end tell
	else
		(* here code to update the existing record *)
		set thePerson to person theName
		try
			set oldMail to get email 1 of thePerson
			set value of oldMail to "newMail@address.com"
		on error errMsg number errnbr
			log errMsg
			make new email at the end of thePerson with properties {value:"newMail@address.com", label:"work"}
		end try
		
		try
			set oldUrl to get url 1 of thePerson
			set value of oldUrl to "http://www.dvorak.com"
		on error errMsg number errnbr
			log errMsg
			make new url at the end of thePerson with properties {value:"http://www.dvorak.com", label:"work"}
		end try
		
		try
			set theAddress to get address 1 of thePerson
			set street of theAddress to "newStreet"
		on error errMsg number errnbr
			log errMsg
			make new address at the end of thePerson with properties {street:"newStreet", zip:thePostalCode, city:theCity, label:"work"}
		end try
	end if
	save addressbook
end tell

Thanks.

The problem was not the one which you described twice.
It was in the syntax used to change some values.

Here is my code with the syntax used to edit datas changed.
It works flawlessly with my original instructions grabbing the record.


(*
properties
birth date (date) : The birth date of this person.
company (boolean) : Is the current record a company or a person.
department (Unicode text) : Department that this person works for.
first name (Unicode text) : The First name of this person.
home page (Unicode text) : The home page of this person.
image (TIFF picture) : Image for person.
job title (Unicode text) : The job title of this person.
last name (Unicode text) : The Last name of this person.
maiden name (Unicode text) : The Maiden name of this person.
middle name (Unicode text) : The Middle name of this person.
nickname (Unicode text) : The Nickname of this person.
note (Unicode text) : Notes for this person.
organization (Unicode text) : Organization that employs this person.
phonetic first name (Unicode text) : The phonetic version of the First name of this person.
phonetic last name (Unicode text) : The phonetic version of the Last name of this person.
phonetic middle name (Unicode text) : The Phonetic version of the Middle name of this person.
suffix (Unicode text) : The Suffix of this person.
title (Unicode text) : The title of this person..
*)
--set firstname to "FirstName"
set thelastname to "LastName"
set theCompany to true
set theStreet to "1234 last street"
set thePostalCode to "5678"
set theCity to "Azerty"
set theMailAddress to "address@address.com"

set theUrl to "http://www.qwerty.com"

tell application "Address Book"
	if not (exists person thelastname) then (* my original test *)
		set the_person to (make new person with properties {last name:thelastname, company:theCompany})
		tell the_person
			make new email at the end of emails with properties {value:theMailAddress, label:"work"}
			make new address at the end of addresses with properties {street:theStreet, zip:thePostalCode, city:theCity, label:"work"}
			make new url at end of urls with properties {value:theUrl, label:"url"}
		end tell -- the_person
	else
		(* here code to update the existing record *)
		set thePerson to get 1st person whose last name is thelastname (* my original instruction *)
		tell thePerson
			set newEmail to "newMail@address.com"
			try
				set value of (get email 1) to newEmail
			on error
				make new email at the end of emails with properties {value:newEmail, label:"work"}
			end try
			set newURL to "http://www.dvorak.com"
			try
				set value of (get url 1) to newURL
			on error
				make new url at the end of urls with properties {value:newURL, label:"work"}
			end try
			set newStreet to "the_new_Street"
			set newZip to "6789"
			set newCity to "Atchoum"
			
			set oldAddress to (get address 1) (* CAUTION ! doesn't return an error if we never create an address *)
			if ((get street of oldAddress) is missing value) and ((get zip of oldAddress) is missing value) and ((get city of oldAddress) is missing value) then
				make new address at the end of addresses
			end if
			
			tell oldAddress
				if newStreet is not missing value then set properties to {street:newStreet}
				if newZip is not missing value then set zip to newZip
				if newCity is not missing value then set city to newCity
			end tell
			
		end tell -- theperson
	end if -- not (exists  .
	save addressbook
end tell

Yvan KOENIG (VALLAURIS, France) lundi 30 novembre 2009 14:32:24