在 Apple 地址簿中查找丢失的生日
我正在尝试清除 Mac 地址簿中的漏洞。作为第一步,我想问我所有的朋友生日,以便能够通过 俗气的 Hallmark 卡。
我的地址簿中需要一个“组”,用于邮件合并个性化消息。
这是我想出的Applescript:
tell application "Address Book"
make new group with properties {name:"No Birthday"}
set birthdayPeople to (get every person whose birth date is greater than date "Monday, January 1, 1900 12:00:00 AM")
repeat with i from 1 to number of items in people
set thePerson to item i of people
if not (birthdayPeople contains thePerson) then
add thePerson to group "No Birthday"
end if
end repeat
save
end tell
它崩溃了,但从错误消息中我无法推断出问题所在:
结果:错误“无法创建 «class azf4» ID \“05F770BA-7492-436B-9B58-E24F494702F8:ABP人\” 应用程序“地址簿”到 输入向量。”来自 «class 的数字 -1700 azf4» id “05F770BA-7492-436B-9B58-E24F494702F8:ABPerson”到矢量
(顺便说一句:我有没有提到这是我的第一个 AppleScript 代码?所以,如果这段代码可以简化,或者变得更优雅,那也是受欢迎的。)
I am trying to clean the holes out of my Mac address book. As a first step I want to ask all my friends for their birthday, to be able to congratulate them with cheesy Hallmark cards.
I need a "group" in my address book, to mailmerge personalized messages from.
This is the Applescript I came up with:
tell application "Address Book"
make new group with properties {name:"No Birthday"}
set birthdayPeople to (get every person whose birth date is greater than date "Monday, January 1, 1900 12:00:00 AM")
repeat with i from 1 to number of items in people
set thePerson to item i of people
if not (birthdayPeople contains thePerson) then
add thePerson to group "No Birthday"
end if
end repeat
save
end tell
It breaks, but from the error messages I cannot deduce what is wrong:
Result: error "Can’t make «class azf4»
id
\"05F770BA-7492-436B-9B58-E24F494702F8:ABPerson\"
of application \"Address Book\" into
type vector." number -1700 from «class
azf4» id
"05F770BA-7492-436B-9B58-E24F494702F8:ABPerson" to vector
(BTW: Did I mention this is my first AppleScript code, EVER? So, if this code can be simplified, or made more elegant, that is welcome too.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我们可以将其简化为五行:
事实证明
add
可以获取列表以及单个对象,因此我们可以跳过循环。 (请注意,如果您使用了循环,则可以使用repeat with thePerson in people ... end Repeat
形式,因为这比您使用的形式更清晰。)接下来,地址簿似乎将缺失的生日存储为缺失值
(实际上是null
),因此我们应该检查这一点,而不是与较早的日期进行比较。因此,为了获取没有生日的人的列表,我们写了每个出生日期缺失值的人
,这正是它所说的。whose
子句过滤前面的列表,使其仅包含与给定谓词匹配的值。然后,我们将该列表添加到我们内联创建的新组中。最后,save addressbook
保存更改并使其可见。但是,在这种情况下,您根本不需要 AppleScript。地址簿支持智能群组;要创建一个,请按住 Option 键并单击“新建组”按钮。选择“无生日”作为智能组的名称,并告诉它匹配“生日”(来自第一个下拉列表)“未设置”(来自第二个下拉列表)的卡片。这将为您提供一组动态更新的没有设定生日的人。
编辑: 看来,虽然
add
在 Leopard 上采用了列表,但在 Snow Leopard 上却没有,因此我们需要使用显式的repeat 循环(也适用于 Leopard):
这与上述解决方案的工作方式几乎相同,只是我们预先进行分组,然后单独添加每个项目。我们不是迭代索引,而是直接迭代元素,因为这就是我们在这里关心的全部。
编辑:对于其他属性,情况类似;事实上,使用智能组时,情况是相同的。从 AppleScript 方面来看,问题在于数据的格式。大多数插槽在未设置时都会出现
缺失值
,但电子邮件
是一个例外。通过测试我们可以看到,它们存储在一个列表中,因此我们需要每个电子邮件地址为 {}
的人。但是,这对我不起作用 - 可能是因为email
是一个列表,但我不确定 - 所以你会想要瞧,一切都应该有效。
加入和排除企业也很容易,但据我所知,地址簿没有提供为他们创建智能组的方法。但是,相关属性是
company
,对于企业来说为true
,对于其他企业来说为false
。因此,要创建一个没有公司的列表,您需要执行以下操作:如果您想要一个包含所有这些条件的主列表,有两种方法。首先,从 AppleScript 中,您获取两个条件和
and
它们,然后添加条件以判断他们是否有电子邮件:另一个选项是从地址簿中执行此操作。您首先需要以 AppleScript 方式创建一个
No Companies
组。然后,您创建一个匹配所有三个条件的智能组(使用+
按钮添加它们):“电子邮件未设置”、“生日未设置”和“卡是 ' 的成员”没有公司”。这可能是最好的选择,尽管不幸的是您必须将 AppleScript 用于No Companies
组(我觉得应该有一种方法,但我看不到它是什么)。We can simplify this down to five lines:
It turns out that
add
can take a list as well as a single object, so we can skip the loop. (Note that if you had used a loop, you could have used therepeat with thePerson in people ... end repeat
form, as that's cleaner than what you had.) Next, it appears that Address Book stores missing birthdays asmissing value
(effectivelynull
), so we should check for that rather than comparing against an early date. Thus, to get a list of the birthdayless people, we writeevery person whose birth date is missing value
, which does exactly what it says. Thewhose
clause filters the preceding list so that it only contains values matching the given predicate. We thenadd
that list to the new group, which we create inline. Finally,save addressbook
saves the changes and makes them visible.However, in this case, you don't need an AppleScript at all. Address Book supports smart groups; to create one, option-click the new group button. Choose "No Birthdays" for the smart group's name, and tell it to match cards for which "Birthday" (from the first dropdown) "is not set" (from the second dropdown). This will give you a dynamically-updating group of people who have no set birthday.
Edit: It seems that while
add
takes a list on Leopard, it doesn't on Snow Leopard, so we'll need to use an explicitrepeat
loop (which works on Leopard too):This works almost the same way as the above solution, except we make the group beforehand, and then add each item individually. Rather than iterating over the indices, we iterate over the elements directly, since that's all we care about here.
Edit: For other properties, things are similar; in fact, when using the smart group, things are identical. From the AppleScript side, the question is the format of the data. Most slots have
missing value
when they're unset, butemail
is an exception. As we can see by testing, they're stored in a list, so we wantevery person whose email is {}
. However, this doesn't work for me—probably becauseemail
is a list, but I'm not sure—so you'll instead wantAnd voilà, everything should work.
In- and excluding businesses is also easy, but as far as I can tell, Address Book doesn't provide a way to create a smart group for them. However, the relevant property is
company
, which istrue
for businesses andfalse
for others. Thus, to create a list without companies, you want to doIf you want one master list with all of these criteria, there are two ways. First, from AppleScript, you take the two condition and
and
them, then add conditioning on whether or not they have an email:The other option is to do this from Address Book. You first need to create a
No Companies
group the AppleScript way. You then create a smart group matching all of three conditions (you add them with the+
button): "Email is not set", "Birthday is not set", and "Card is a member of 'No Companies'". This is probably the best option, although it's unfortunate that you have to use AppleScript for theNo Companies
group (I feel like there should be a way, but I can't see what it is).