I have a 2,500+ entry address book, much of which is sorted into groups. However, I know some cards have no group, and I can’t for the life of me figure out how to identify them. SmartGroups seem to be no help.
My AppleScript skills are minimal, but I’m trying to adapt chunks of existing Address Book scripts I’ve found online. I’m using 10.4.11 on an iBook G4; Address Book 4.0.6; and Script Editor 2.1.1
I figure the simplest way to do this is to put all cards in a new group (“NoGroup”), then cycle through each existing group, removing any matches. At the end, all that’s left should be contacts without a group.
I’ve gotten as far as creating the new group and dumping all existing contacts into it. I then tried to set it up to identify and remove cards that belong to a single group (hard-coded as my Friends/Family group, for simplicity); I figured once I got this down, I could figure out how to cycle through all the groups in turn.
However, now it’s choking on my if statement, even though it’s nearly identical to an if statement I found in a (working) script I found on the Web. Any suggestions? And any suggestions for accomplishing the end goal? I’d love to learn how to do it myself, but that doesn’t seem to be working…
Here’s what I’ve got:
tell application "Address Book"
activate
set NoGroup to "NoGroup"
set theUnGroupByID to make new group with properties {name:NoGroup}
add every person to theUnGroupByID
save addressbook
try
set nameOfEveryGroup to name of every group
end try
set theGroupByID to group named "Friends/Family"
set allCards to every person of theGroupByID
repeat with i from 1 to number of people
set thisPerson to person i as list
if thisPerson is in allCards then remove person i from theUnGroupByID
end repeat
end tell
Thanks in advance!
Model: iBook G4 1.07 GHz 768 MB RAM
Browser: Firefox 2.0.0.14
Operating System: Mac OS X (10.5)
OK, well, I poked around some more, and thought I (almost) had it. See below.
It seemed to cycle through the groups OK, and identify the members of the groups (that’s what the dialog displays are about – giving me some feedback about what it’s doing). But in fact, it doesn’t actually remove anything from the NoGroup group… (I also realize that if it did work, it would leave NoGroup empty; I’ll have to figure out some way of telling the script not to delete all NoGroup from NoGroup…)
Anyway, all suggestions welcome. And maybe there’s a simpler way of doing this.
tell application "Address Book"
activate
set NoGroup to "NoGroup"
set theUnGroupByID to make new group with properties {name:NoGroup}
add every person to theUnGroupByID
save addressbook
try
set nameOfEveryGroup to name of every group
end try
repeat with i from 1 to number of groups
set thisGroupName to item i of nameOfEveryGroup
display dialog thisGroupName
set thisGroup to group thisGroupName
set peopleOfThisGroup to name of every person of thisGroup
set theResult to choose from list peopleOfThisGroup with prompt "These are the members of the group."
set thisGroupsCards to every person of thisGroup
repeat with j from 1 to number of people
set thisPerson to person j as list
if thisPerson is in thisGroupsCards then remove thisPerson from group "NoGroup"
end repeat
end repeat
end tell
Model: iBook G4 1.07 GHz 768 MB RAM
Browser: Firefox 2.0.0.14
Operating System: Mac OS X (10.5)
adding all people to new group and removing one by one is wasted time
This might be the fastest way, it puts once the IDs of the people of all groups in a flattened list
and checks, if the given ID is in the list.
The group “NoGroup” will be deleted and recreated if the group already exists
and smart groups won’t be considered
property NoGroup : "NoGroup"
tell application "Address Book"
set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set GroupIDs to id of every person of (groups whose id does not end with "ABSmartGroup") as text
set AppleScript's text item delimiters to ASTID
if exists group NoGroup then delete group NoGroup
set theUnGroupByID to make new group with properties {name:NoGroup}
tell people to set {allPeople, allID, cnt} to {it, its id, count it}
repeat with onePerson from 1 to cnt
if GroupIDs does not contain item onePerson of allID then
add item onePerson of allPeople to theUnGroupByID
end if
end repeat
end tell
Another way to check for people in no group would be:
people whose groups is equal to {} -- "{}" indicates an empty list.
So something like the following should work. It doesn’t delete the group if it’s already there.
set NoGroup to "NoGroup" -- Name of group to use.
tell application "Address Book"
-- If the group is not there make it.
if (name of groups) does not contain NoGroup then
make new group with properties {name:NoGroup}
end if
-- Get all people who have no group set and add them to this group.
add (people whose groups is equal to {}) to group NoGroup
-- To update the UI.
save addressbook
end tell
Wonderful – thanks to both of you! Both are much more elegant solutions, from what I can read of them.
Just for the record, Mike, yours took 7.6 seconds; Stefan, yours seemed like it would take a little longer, but then choked on this line at one point (well into running):
add item onePerson of allPeople to theUnGroupByID
Sadly, the script is beyond me, so I can’t really guess what might have happened…