Delphi Outlook Contact Automation-遍历ContactItem的所有属性

Delphi Outlook Contact Automation-遍历ContactItem的所有属性,delphi,properties,outlook,automation,contacts,Delphi,Properties,Outlook,Automation,Contacts,我目前正在编写一个小程序,将Outlook联系人的所有数据元素提取到新的CRM数据库中。我已经导入了必要的类型库,并产生了以下代码(就快到了!!!) ` Contacts:=NameSpace.GetDefaultFolder(olFolderContacts); 对于i:=1到Contacts.Items.Count do 开始 联系人:=联系人。项目。项目(i); {现在您可以读取联系人的任何属性。例如,全名和 电子邮件地址} //ShowMessage(Contact.FullName+“

我目前正在编写一个小程序,将Outlook联系人的所有数据元素提取到新的CRM数据库中。我已经导入了必要的类型库,并产生了以下代码(就快到了!!!)

`

Contacts:=NameSpace.GetDefaultFolder(olFolderContacts);
对于i:=1到Contacts.Items.Count do
开始
联系人:=联系人。项目。项目(i);
{现在您可以读取联系人的任何属性。例如,全名和
电子邮件地址}
//ShowMessage(Contact.FullName+“”);
备忘录1.行。添加(Contact.FullName+“”);
Memo1.Lines.Add(IntToStr(Contact.ItemProperties.Count)+'>');
对于j:=0的Contact.ItemProperties.Count-1 do
如果Contact.ItemProperties.Item(j)为空,则
备忘录1.Lines.Add(Contact.ItemProperties.Item(j));
结束

迭代通过联系人工作正常(我在备忘录中看到)。我的问题是第二个“for”循环试图检查联系人的所有168个字段(168也显示在备忘录中)

有人能帮我解释一下迭代每个联系人项目的每个属性吗?我已经找到了一些答案,但我需要/想进一步深入研究

提前谢谢


比尔

用这种方式与null进行比较可能是个问题。尝试:

for j := 0 to Contact.ItemProperties.Count -1 do
  Memo1.Lines.Add(Contact.ItemProperties.Item(j).Name);
甚至:

for j := 0 to Contact.ItemProperties.Count -1 do
  if Contact.ItemProperties.Item(j).Name <> null then
    Memo1.Lines.Add(Contact.ItemProperties.Item(j).Name);
你为什么关心所有的财产?PR_CHANGE_KEY有用吗?还是公关MDB_供应商?还是存储记录密钥

为什么不只处理应用程序知道的属性

如果要查看MAPI级别的所有属性,请查看联系人(单击IMessage按钮)

至于你最初的问题,你在所有地方都使用了多点符号,无论是对于物品还是物品属性。在进入循环之前缓存集合,并通过将变量设置为nil显式释放变量:

Contacts := NameSpace.GetDefaultFolder(olFolderContacts);

  vItems := Contacts.Items;
  for i := 1 to vItems .Count do
  begin
    Contact := vItems .Item(i);
    {now you can read any property of contact. For example, full name and
     email address}
//    ShowMessage(Contact.FullName + ' <' + Contact.Email1Address + '>');
    Memo1.Lines.Add(Contact.FullName + ' <' + Contact.Email1Address + '>');
    Memo1.Lines.Add(IntToStr(Contact.ItemProperties.Count) + '>');

vItemProperties := Contact.ItemProperties;
for j := 0 to vItemProperties.Count -1 do
 vItemProperty := vItemProperties.Item(j);
 if vItemProperty <> null then
   Memo1.Lines.Add(vItemProperty.Name);
   vItemProperty := nil;
Contacts:=NameSpace.GetDefaultFolder(olFolderContacts);
vItems:=联系人。项目;
对于i:=1到vItems.Count do
开始
联系人:=第(i)项中的维特姆斯;
{现在您可以读取联系人的任何属性。例如,全名和
电子邮件地址}
//ShowMessage(Contact.FullName+“”);
备忘录1.行。添加(Contact.FullName+“”);
Memo1.Lines.Add(IntToStr(Contact.ItemProperties.Count)+'>');
vItemProperties:=Contact.ItemProperties;
对于j:=0到VitemProperty。计数-1 do
vItemProperty:=vItemProperty.项目(j);
如果vItemProperty为空,则
备注1.Lines.Add(vItemProperty.Name);
vItemProperty:=零;

好的,在TLB for office中度过了一段高质量的时间后,我能够浏览每个联系人的属性,无论是否有用。RTFBody属性必须从Unicode转换为ANSI WideString,附件作为一个集合(计数非常容易迭代),而分派值则是我刚刚忽略的。通过学习,MSDN Office Interop online docs在处理字段类型方面提供了很好的帮助。长时间的点表示法是必要的,因为我似乎无法让分组工作,但降低每一个级别都很好。接下来是重要的部分。一如既往地感谢您的投入

 Memo1.Lines.Add(IntToStr(Contacts.Items.Count) + '>');
 for i := 1 to Contacts.Items.Count do
  begin
    Contact := Contacts.Items.Item(i);
  {now you can read any property of contact. For example, full name and
    email address}

    for j := 0 to Contact.ItemProperties.Count -1 do
     begin
      ContactProperty := Contact.ItemProperties.Item(j);
      if not VarIsNull(ContactProperty.Value) then

       if ContactProperty.Name = 'RTFBody' then
        begin
         RTFByte := ContactProperty.Value;
         SetString(tANSIStr, PAnsiChar(@RTFByte[0]), Length (ContactProperty.Value));
         Memo1.Lines.Add(ContactProperty.Name + ' <' + tANSIstr +  '>');
         RichEdit1.Lines.Add(tANSIstr);
        end
       else

       if ContactProperty.Name = 'Attachments' then
        begin
         Attachments := Contact.Attachments;
         for k := 1 to Attachments.Count do
          begin
           ContactAttachment := Attachments.Item(k);
           Memo1.Lines.Add('Attachment.FileName <' + ContactAttachment.FileName +  '>');
          end;
        end
     end;
Memo1.Lines.Add(IntToStr(Contacts.Items.Count)+'>';
对于i:=1到Contacts.Items.Count do
开始
联系人:=联系人。项目。项目(i);
{现在您可以读取联系人的任何属性。例如,全名和
电子邮件地址}
对于j:=0的Contact.ItemProperties.Count-1 do
开始
ContactProperty:=Contact.ItemProperties.Item(j);
如果不是VarisAll(ContactProperty.Value),则
如果ContactProperty.Name='RTFBody',则
开始
RTFByte:=ContactProperty.Value;
设置字符串(tANSIStr,PAnsiChar(@RTFByte[0]),长度(ContactProperty.Value));
备注1.Lines.Add(ContactProperty.Name+“”);
RichEdit1.行。添加(tANSIstr);
结束
其他的
如果ContactProperty.Name='Attachments',则
开始
附件:=联系人。附件;
对于k:=1到附件。计数do
开始
ContactAttachment:=附件。项目(k);
Memo1.Lines.Add('Attachment.FileName');
结束;
结束
结束;

我怀疑Contact.ItemProperties.Item(j)能否成功地将每个变量转换为字符串。如果一个属性是数组呢?我建议使用varisnll,然后检测变量类型并适当地处理转换。Dmitry(“您为什么关心所有属性?”)由于MS可以随意添加/删除属性,因此我认为控制我自己情况的最佳方法就是将它们全部(属性)收集起来只要挑一个我想要的就行了。多亏了Jan&Blury为tag团队工作!
Contacts := NameSpace.GetDefaultFolder(olFolderContacts);

  vItems := Contacts.Items;
  for i := 1 to vItems .Count do
  begin
    Contact := vItems .Item(i);
    {now you can read any property of contact. For example, full name and
     email address}
//    ShowMessage(Contact.FullName + ' <' + Contact.Email1Address + '>');
    Memo1.Lines.Add(Contact.FullName + ' <' + Contact.Email1Address + '>');
    Memo1.Lines.Add(IntToStr(Contact.ItemProperties.Count) + '>');

vItemProperties := Contact.ItemProperties;
for j := 0 to vItemProperties.Count -1 do
 vItemProperty := vItemProperties.Item(j);
 if vItemProperty <> null then
   Memo1.Lines.Add(vItemProperty.Name);
   vItemProperty := nil;
 Memo1.Lines.Add(IntToStr(Contacts.Items.Count) + '>');
 for i := 1 to Contacts.Items.Count do
  begin
    Contact := Contacts.Items.Item(i);
  {now you can read any property of contact. For example, full name and
    email address}

    for j := 0 to Contact.ItemProperties.Count -1 do
     begin
      ContactProperty := Contact.ItemProperties.Item(j);
      if not VarIsNull(ContactProperty.Value) then

       if ContactProperty.Name = 'RTFBody' then
        begin
         RTFByte := ContactProperty.Value;
         SetString(tANSIStr, PAnsiChar(@RTFByte[0]), Length (ContactProperty.Value));
         Memo1.Lines.Add(ContactProperty.Name + ' <' + tANSIstr +  '>');
         RichEdit1.Lines.Add(tANSIstr);
        end
       else

       if ContactProperty.Name = 'Attachments' then
        begin
         Attachments := Contact.Attachments;
         for k := 1 to Attachments.Count do
          begin
           ContactAttachment := Attachments.Item(k);
           Memo1.Lines.Add('Attachment.FileName <' + ContactAttachment.FileName +  '>');
          end;
        end
     end;