Adding a Contact with multiple e-mail addresses to a Distribution

  • Thread starter Thread starter David Lingren
  • Start date Start date
D

David Lingren

We are trying to build an Outlook Contacts folder from an Access database.
There are several Distribution Lists we want to add to the folder.

How can I programatically create a distribution list entry for an Outlook
Contact that has multiple e-mail addresses?

In the example below (running in Microsoft Access) "John Smith" has one
e-mail address in his Contact item and Jim Jones has two e-mail addresses in
his Contact item.

The first CreateRecipient works fine. John Smith appears in the distribution
list, his display name is "John Smith ([email protected])" and the icon to the
left of his name is the Outlook Contact busines card icon. If you
double-click on the entry the Contact form comes up.

The second CreateRecipient fails. The Resolve function returns false and
nothing is added to the list.

The third CreateRecipient succeeds, but the Display Name is "Jim Jones" and
the icon to the left of the name is the notecard that indicates a non-Contact
entry. This entry looks like it is NOT associated with an Outlook Contact.

However - if you double-click on the entry the Contact form comes up, so the
association gets made somehow. It's just that the icon and name are different.

Note that if you use the "Select Members" dialog the icon and name are set
correctly, but you can't do it from VBA. It seems a small difference, but we
want the lists to "look right".

Any ideas?

PS

Many bonus points awarded if you can tell me how to change the user profile
used in the session. The Logon and Logoff methods don't seem to work at all.
We have to manually start Outlook with the correct profile before we run the
program.




Sub AddNewMember()
'Adds a member to a new distribution list
Dim ol As New Outlook.Application
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
Dim oFolder As Outlook.Folder
Dim oDistListItem As Outlook.DistListItem
Dim oRecipient As Outlook.Recipient

On Error Resume Next
' ol.Session.Logoff
' ol.Session.Logon "ETaiko", , True, True

Set oStore = ol.Session.Stores("ETaiko Folders")
Set oRoot = oStore.GetRootFolder
Set oFolder = oRoot.folders("Contacts")

Set oDistListItem = oFolder.Items.Add(olDistributionListItem)
oDistListItem.DLName = "AAA Test DGroup"

'Create recipients for distlist
Set oRecipient = ol.Session.CreateRecipient("John Smith")
oRecipient.Resolve
Debug.Print "1 " & oRecipient.Resolve
oDistListItem.AddMember oRecipient
oDistListItem.Close (olSave)

Set oRecipient = ol.Session.CreateRecipient("Jim Jones")
Debug.Print "2 " & oRecipient.Resolve
oDistListItem.AddMember oRecipient
Debug.Print Err.Number & " " & Err.Description
oDistListItem.Close (olSave)

Set oRecipient = ol.Session.CreateRecipient("Jim Jones ([email protected])")
Debug.Print "3 " & oRecipient.Resolve
oDistListItem.AddMember oRecipient
Debug.Print Err.Number & " " & Err.Description
oDistListItem.Close (olSave)

End Sub
 
Thanks for your quick reaponse, but passing the e-mail address to
CreateRecipient doesn't work, either. The icon displayed is the non-contact
"notecard" and the Display Name contains the e-mail address, not the contact
name.
 
Dmitry,

Thanks for your suggestion of 2/24. I downloaded and installed Outlook
Redemption and have made considerable progress. However, I have a related
problem.

I am trying to extract Contacts and Personal Distribution Lists to an Access
database so we can analyse them. I can't find a way to tell which members of
a MAPIPDL are related to Contacts in the address book so I can retrieve the
"FileAs" property that uniquely identifies each of them.

The code below is as close as I can get. The problem is that the
"oMember.GetContact" method always returns Nothing for members of a MAPIPDL.
Is there another way I can get from a MAPIPDL member to the related Contact?

Outlook (2007) does this somehow...

Thanks for all your help so far. By the way, OutlookSpy is terrific!

David Lingren


Sub EnumerateRDOAddressLists()

' Set up Redemption Objects.
Dim oSession As Redemption.RDOSession
Dim oAddressBook As Redemption.RDOAddressBook
Dim oAddressLists As Redemption.RDOAddressLists
Dim oAddresslist As Redemption.RDOAddressList
Dim oAddressEntries As Redemption.RDOAddressEntries
Dim oAddressEntry As Redemption.RDOAddressEntry
Dim oContact As Redemption.RDOContactItem
Dim oMembers As Redemption.RDOAddressEntries
Dim oMember As Redemption.RDOAddressEntry

Set oSession = New RDOSession
oSession.Logon ("ETaiko")

Set oAddressBook = oSession.AddressBook
Set oAddressLists = oAddressBook.AddressLists

For Each oAddresslist In oAddressLists
Debug.Print oAddresslist.Name

Set oAddressEntries = oAddresslist.AddressEntries
For Each oAddressEntry In oAddressEntries
Debug.Print oAddressEntry.Type & " " & oAddressEntry.Address & "
" & oAddressEntry.Name

If oAddressEntry.Type = "MAPIPDL" Then
Set oContact = oAddressEntry.GetContact
Set oMembers = oAddressEntry.Members
Debug.Print "MAPIPDL " & oContact.FileAs & " " &
oMembers.Count

For Each oMember In oMembers
Debug.Print "Member " & oMember.Name & ", " &
oMember.Address & ", " & oMember.Type
Set oContact = oMember.GetContact
If Not (oContact Is Nothing) Then
Debug.Print "Member FileAs " & oContact.FileAs
End If
Next
Else
Set oContact = oAddressEntry.GetContact
If Not (oContact Is Nothing) Then Debug.Print "CONTACT " &
oContact.FileAs
End If
Next
Next

Set oMember = Nothing
Set oMembers = Nothing
Set oContact = Nothing
Set oAddressEntry = Nothing
Set oAddressEntries = Nothing
Set oAddresslist = Nothing
Set oAddressLists = Nothing
oSession.Logoff
Set oSession = Nothing
End Sub
 
I hads no problem with the following script (assumign you have a contact
named "Dmitry Streblechenko").

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Contacts = Session.GetDefaultFolder(olFolderContacts)
set DL = Contacts.Items.Add("IPM.DistList")
DL.DLName = "test contact"
set Contact = Contacts.Items("Dmitry Streblechenko") 'add email1 address to
the DL
DL.AddContact Contact, 0
DL.Save

set AE = DL.Members(1)
set Contact = AE.GetContact
MsgBox Contact.FileAs

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
Dimtry,

The solution you propose works in most cases, but not all. If the contact
has a "Title" property, such as "Mr." or "Ms.", the Contacts.Items search
will fail. The value in the "Name" field of the address entry is not always
enough to retrieve the corresponding contact item. In my application, I am
going through the address entries in a distribution list and trying to find
the corresponding contact items. We've got thousands of contacts and list
entries.

I have made some further progress on this problem, but haven't reached the
end.

I used the Redemption.MAPIUtils.HrGetPropList method to retrieve the
properties for each AddressEntry. The entries that match a Contact item have
a property 0x3A120102, the "PR_ORIGINAL_ENTRYID". The MAPI reference says
"This property is one of the properties that contain information about the
original source of a copied entry."

Going back to the Contact item that matches the AddressEntry, I find
properties 0x81140102, and 0x81150102 whose values match the 0x3A120102
property in the coprresponding address entry. It looks like these are unique
identifiers for Email1Address, Email2Address, etc.

So, if I can do some sort of query like "find the item whose 0x8114 (or
0x8115 or ...) property is ..." I'm done. Is this possible?

Another problem - these properties are all PT_BINARY, i.e. byte arrays. The
MAPI documentation says that entry ids are strings. How do I go from the byte
array to the equivalent string?


In the interim this is what seems to work for the data I've tested against:

FullName = oAddressEntry.Name
lParen = InStr(1, FullName, "(")
If lParen > 2 Then FullName = Left(FullName, lParen - 2)

Set oContactEntry = Nothing
SQLEncode MemberName, FullName ' handle single quotes in the name
Set oContacts = oItems.Restrict("SELECT * FROM folder WHERE [FullName] LIKE
'%" & MemberName & "%'")
If oContacts.Count = 1 Then
Set oContactEntry = oContacts(1)
Else
Set oContact = Nothing
End If

It's not perfect...

Thanks for your continuing interest in this issue.

David Lingren
 
I do not suggest that you need to search a contact for a particular name,
just gave you an example of creating a new DL with a contact and then
reading the RDOAddressEntry.GetContact worked.
What is the value of the EntryID property when GetContcat returns null?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
David Lingren said:
Dimtry,

The solution you propose works in most cases, but not all. If the contact
has a "Title" property, such as "Mr." or "Ms.", the Contacts.Items search
will fail. The value in the "Name" field of the address entry is not
always
enough to retrieve the corresponding contact item. In my application, I am
going through the address entries in a distribution list and trying to
find
the corresponding contact items. We've got thousands of contacts and list
entries.

I have made some further progress on this problem, but haven't reached the
end.

I used the Redemption.MAPIUtils.HrGetPropList method to retrieve the
properties for each AddressEntry. The entries that match a Contact item
have
a property 0x3A120102, the "PR_ORIGINAL_ENTRYID". The MAPI reference says
"This property is one of the properties that contain information about the
original source of a copied entry."

Going back to the Contact item that matches the AddressEntry, I find
properties 0x81140102, and 0x81150102 whose values match the 0x3A120102
property in the coprresponding address entry. It looks like these are
unique
identifiers for Email1Address, Email2Address, etc.

So, if I can do some sort of query like "find the item whose 0x8114 (or
0x8115 or ...) property is ..." I'm done. Is this possible?

Another problem - these properties are all PT_BINARY, i.e. byte arrays.
The
MAPI documentation says that entry ids are strings. How do I go from the
byte
array to the equivalent string?


In the interim this is what seems to work for the data I've tested
against:

FullName = oAddressEntry.Name
lParen = InStr(1, FullName, "(")
If lParen > 2 Then FullName = Left(FullName, lParen - 2)

Set oContactEntry = Nothing
SQLEncode MemberName, FullName ' handle single quotes in the name
Set oContacts = oItems.Restrict("SELECT * FROM folder WHERE [FullName]
LIKE
'%" & MemberName & "%'")
If oContacts.Count = 1 Then
Set oContactEntry = oContacts(1)
Else
Set oContact = Nothing
End If

It's not perfect...

Thanks for your continuing interest in this issue.

David Lingren



Dmitry Streblechenko said:
I hads no problem with the following script (assumign you have a contact
named "Dmitry Streblechenko").

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Contacts = Session.GetDefaultFolder(olFolderContacts)
set DL = Contacts.Items.Add("IPM.DistList")
DL.DLName = "test contact"
set Contact = Contacts.Items("Dmitry Streblechenko") 'add email1 address
to
the DL
DL.AddContact Contact, 0
DL.Save

set AE = DL.Members(1)
set Contact = AE.GetContact
MsgBox Contact.FileAs

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
I do not suggest that you need to search a contact for a particular name,
just gave you an example of creating a new DL with a contact and then
reading the RDOAddressEntry.GetContact worked.
What is the value of the EntryID property when GetContcat returns null?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
David Lingren said:
Dimtry,

The solution you propose works in most cases, but not all. If the contact
has a "Title" property, such as "Mr." or "Ms.", the Contacts.Items search
will fail. The value in the "Name" field of the address entry is not
always
enough to retrieve the corresponding contact item. In my application, I am
going through the address entries in a distribution list and trying to
find
the corresponding contact items. We've got thousands of contacts and list
entries.

I have made some further progress on this problem, but haven't reached the
end.

I used the Redemption.MAPIUtils.HrGetPropList method to retrieve the
properties for each AddressEntry. The entries that match a Contact item
have
a property 0x3A120102, the "PR_ORIGINAL_ENTRYID". The MAPI reference says
"This property is one of the properties that contain information about the
original source of a copied entry."

Going back to the Contact item that matches the AddressEntry, I find
properties 0x81140102, and 0x81150102 whose values match the 0x3A120102
property in the coprresponding address entry. It looks like these are
unique
identifiers for Email1Address, Email2Address, etc.

So, if I can do some sort of query like "find the item whose 0x8114 (or
0x8115 or ...) property is ..." I'm done. Is this possible?

Another problem - these properties are all PT_BINARY, i.e. byte arrays.
The
MAPI documentation says that entry ids are strings. How do I go from the
byte
array to the equivalent string?


In the interim this is what seems to work for the data I've tested
against:

FullName = oAddressEntry.Name
lParen = InStr(1, FullName, "(")
If lParen > 2 Then FullName = Left(FullName, lParen - 2)

Set oContactEntry = Nothing
SQLEncode MemberName, FullName ' handle single quotes in the name
Set oContacts = oItems.Restrict("SELECT * FROM folder WHERE [FullName]
LIKE
'%" & MemberName & "%'")
If oContacts.Count = 1 Then
Set oContactEntry = oContacts(1)
Else
Set oContact = Nothing
End If

It's not perfect...

Thanks for your continuing interest in this issue.

David Lingren



Dmitry Streblechenko said:
I hads no problem with the following script (assumign you have a contact
named "Dmitry Streblechenko").

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Contacts = Session.GetDefaultFolder(olFolderContacts)
set DL = Contacts.Items.Add("IPM.DistList")
DL.DLName = "test contact"
set Contact = Contacts.Items("Dmitry Streblechenko") 'add email1 address
to
the DL
DL.AddContact Contact, 0
DL.Save

set AE = DL.Members(1)
set Contact = AE.GetContact
MsgBox Contact.FileAs

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
Dmitry,

Your clarification led me to do some further testing, which solved one of my
two problems. Also, I realize that my earlier posts were somewhat confusing.

My problem began when I tried to use the Outlook Object Model to go through
the MAPIPDL entries in the Contacts folder. If you use the OOM, the
GetContact method does not work - it returns Null. You can see this with
OutlookSpy if you open a distribution list, retrieve a member and browse the
Address Entry of the member.

My first post on 2/20 assumed that GetContact did not work and the only data
available was the EntryName in the address entry. Ignore that.

My third post on 2/27 was a different approach to the problem - use the
AddressLists instead of the Contacts folder. This also fails in the way I
described.

HOWEVER - your posts on 3/1 and 3/3 made me realize that I had never tried
the GetContact method AFTER I switched from the OOM to your RDO objects. I
just tried the GetContact method on the RDOAddressEntry and it works! That
solves my first problem.

My second problem is still unsolved. Your post on 3/1 is a little different
from my problem. You start by finding a contact, then creating a distribution
list and adding a contact to it when you already have an object reference to
the contact.

My application has an Access database with the name of an existing
distribution list and the name and address information for the contacts I
want to add to the list. I have to use information in the database to look up
the contact and get an object reference for it. I need to extract a unique
identifier for the contact when I build the database so I can later use the
identifier to look up the contact as I build the distribution list.

In other words,

step 1 - read the Contacts folder and build an Access database
step 2 - work with the data in Access to generate distribution lists
step 3 - read the database, look up the contacts and add them to the lists

I can't save the object reference in a database and use it later to get the
object back. That is why I am trying to use the EntryIDs I found in the
property collection to get a unique key I can save and then use later to get
the right contact.

I hope that clearly describes my problem. I can post all my code if you want
it.

Thanks for your patience and for sticking with me on this project! You are
really helping me.

David Lingren


Dmitry Streblechenko said:
I do not suggest that you need to search a contact for a particular name,
just gave you an example of creating a new DL with a contact and then
reading the RDOAddressEntry.GetContact worked.
What is the value of the EntryID property when GetContcat returns null?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
David Lingren said:
Dimtry,

The solution you propose works in most cases, but not all. If the contact
has a "Title" property, such as "Mr." or "Ms.", the Contacts.Items search
will fail. The value in the "Name" field of the address entry is not
always
enough to retrieve the corresponding contact item. In my application, I am
going through the address entries in a distribution list and trying to
find
the corresponding contact items. We've got thousands of contacts and list
entries.

I have made some further progress on this problem, but haven't reached the
end.

I used the Redemption.MAPIUtils.HrGetPropList method to retrieve the
properties for each AddressEntry. The entries that match a Contact item
have
a property 0x3A120102, the "PR_ORIGINAL_ENTRYID". The MAPI reference says
"This property is one of the properties that contain information about the
original source of a copied entry."

Going back to the Contact item that matches the AddressEntry, I find
properties 0x81140102, and 0x81150102 whose values match the 0x3A120102
property in the coprresponding address entry. It looks like these are
unique
identifiers for Email1Address, Email2Address, etc.

So, if I can do some sort of query like "find the item whose 0x8114 (or
0x8115 or ...) property is ..." I'm done. Is this possible?

Another problem - these properties are all PT_BINARY, i.e. byte arrays.
The
MAPI documentation says that entry ids are strings. How do I go from the
byte
array to the equivalent string?


In the interim this is what seems to work for the data I've tested
against:

FullName = oAddressEntry.Name
lParen = InStr(1, FullName, "(")
If lParen > 2 Then FullName = Left(FullName, lParen - 2)

Set oContactEntry = Nothing
SQLEncode MemberName, FullName ' handle single quotes in the name
Set oContacts = oItems.Restrict("SELECT * FROM folder WHERE [FullName]
LIKE
'%" & MemberName & "%'")
If oContacts.Count = 1 Then
Set oContactEntry = oContacts(1)
Else
Set oContact = Nothing
End If

It's not perfect...

Thanks for your continuing interest in this issue.

David Lingren



Dmitry Streblechenko said:
I hads no problem with the following script (assumign you have a contact
named "Dmitry Streblechenko").

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Contacts = Session.GetDefaultFolder(olFolderContacts)
set DL = Contacts.Items.Add("IPM.DistList")
DL.DLName = "test contact"
set Contact = Contacts.Items("Dmitry Streblechenko") 'add email1 address
to
the DL
DL.AddContact Contact, 0
DL.Save

set AE = DL.Members(1)
set Contact = AE.GetContact
MsgBox Contact.FileAs

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
If you save the entry id, you can reopen the item at any later point using
Namespace.GetItemFromID.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
David Lingren said:
Dmitry,

Your clarification led me to do some further testing, which solved one of
my
two problems. Also, I realize that my earlier posts were somewhat
confusing.

My problem began when I tried to use the Outlook Object Model to go
through
the MAPIPDL entries in the Contacts folder. If you use the OOM, the
GetContact method does not work - it returns Null. You can see this with
OutlookSpy if you open a distribution list, retrieve a member and browse
the
Address Entry of the member.

My first post on 2/20 assumed that GetContact did not work and the only
data
available was the EntryName in the address entry. Ignore that.

My third post on 2/27 was a different approach to the problem - use the
AddressLists instead of the Contacts folder. This also fails in the way I
described.

HOWEVER - your posts on 3/1 and 3/3 made me realize that I had never tried
the GetContact method AFTER I switched from the OOM to your RDO objects. I
just tried the GetContact method on the RDOAddressEntry and it works! That
solves my first problem.

My second problem is still unsolved. Your post on 3/1 is a little
different
from my problem. You start by finding a contact, then creating a
distribution
list and adding a contact to it when you already have an object reference
to
the contact.

My application has an Access database with the name of an existing
distribution list and the name and address information for the contacts I
want to add to the list. I have to use information in the database to look
up
the contact and get an object reference for it. I need to extract a unique
identifier for the contact when I build the database so I can later use
the
identifier to look up the contact as I build the distribution list.

In other words,

step 1 - read the Contacts folder and build an Access database
step 2 - work with the data in Access to generate distribution lists
step 3 - read the database, look up the contacts and add them to the lists

I can't save the object reference in a database and use it later to get
the
object back. That is why I am trying to use the EntryIDs I found in the
property collection to get a unique key I can save and then use later to
get
the right contact.

I hope that clearly describes my problem. I can post all my code if you
want
it.

Thanks for your patience and for sticking with me on this project! You are
really helping me.

David Lingren


Dmitry Streblechenko said:
I do not suggest that you need to search a contact for a particular name,
just gave you an example of creating a new DL with a contact and then
reading the RDOAddressEntry.GetContact worked.
What is the value of the EntryID property when GetContcat returns null?

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
David Lingren said:
Dimtry,

The solution you propose works in most cases, but not all. If the
contact
has a "Title" property, such as "Mr." or "Ms.", the Contacts.Items
search
will fail. The value in the "Name" field of the address entry is not
always
enough to retrieve the corresponding contact item. In my application, I
am
going through the address entries in a distribution list and trying to
find
the corresponding contact items. We've got thousands of contacts and
list
entries.

I have made some further progress on this problem, but haven't reached
the
end.

I used the Redemption.MAPIUtils.HrGetPropList method to retrieve the
properties for each AddressEntry. The entries that match a Contact item
have
a property 0x3A120102, the "PR_ORIGINAL_ENTRYID". The MAPI reference
says
"This property is one of the properties that contain information about
the
original source of a copied entry."

Going back to the Contact item that matches the AddressEntry, I find
properties 0x81140102, and 0x81150102 whose values match the 0x3A120102
property in the coprresponding address entry. It looks like these are
unique
identifiers for Email1Address, Email2Address, etc.

So, if I can do some sort of query like "find the item whose 0x8114 (or
0x8115 or ...) property is ..." I'm done. Is this possible?

Another problem - these properties are all PT_BINARY, i.e. byte arrays.
The
MAPI documentation says that entry ids are strings. How do I go from
the
byte
array to the equivalent string?


In the interim this is what seems to work for the data I've tested
against:

FullName = oAddressEntry.Name
lParen = InStr(1, FullName, "(")
If lParen > 2 Then FullName = Left(FullName, lParen - 2)

Set oContactEntry = Nothing
SQLEncode MemberName, FullName ' handle single quotes in the name
Set oContacts = oItems.Restrict("SELECT * FROM folder WHERE [FullName]
LIKE
'%" & MemberName & "%'")
If oContacts.Count = 1 Then
Set oContactEntry = oContacts(1)
Else
Set oContact = Nothing
End If

It's not perfect...

Thanks for your continuing interest in this issue.

David Lingren



:

I hads no problem with the following script (assumign you have a
contact
named "Dmitry Streblechenko").

set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Contacts = Session.GetDefaultFolder(olFolderContacts)
set DL = Contacts.Items.Add("IPM.DistList")
DL.DLName = "test contact"
set Contact = Contacts.Items("Dmitry Streblechenko") 'add email1
address
to
the DL
DL.AddContact Contact, 0
DL.Save

set AE = DL.Members(1)
set Contact = AE.GetContact
MsgBox Contact.FileAs

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
Dmitry,

Your suggestion solves part of the problem, but I did not make clear the
other part of my problem.

Using the RDO objects and GetContact I can find the Contact item that
matches a MAPIPDL member. I can't reliably find the "address type" in the
Contact that matches the MAPIPDL member entry (i.e. atEmail1 ... atOtherFax).

I have found that Outlook behaves oddly if you add a Contact to a MAPIPDL
and then later change or delete the e-mail address in the Contact item or
delete the entire Contact item. For example, try the following:

1. add a Contact to a MAPIPDL
2. delete the Contact
3. create a new e-mail message to the MAPIPDL

You will find that name and e-mail address for the deleted Contact still
appears in the message you create. If you open the MAPIPDL and double-click
on the entry for the deleted member, you get a "item has been deleted or
moved" warning. If you access the MAPIPDL from code, you get the deleted
item's MAPIPDL entry as if nothing has changed! So, if I call GetContact and
it fails, how do I tell the difference between a deleted Contact and an SMTP
entry that never had a Contact?

OR

1. add a Contact to a MAPIPDL
2. change the Contact's e-mail address
3. create a new e-mail message to the MAPIPDL

You will find that the message contains the new e-mail address, but if you
access the MAPIPDL you still get the OLD (wrong) address in the Recipient and
Address Entry objects! If you call GetContact, it will work but there's no
way to match the address in the MAPIPDL back to the correct address type in
the Contact.

Outlook obviously uses the hidden properties, such as the 0x3A120102
"PR_ORIGINAL_ENTRYID", to match the MAPIPDL member back to the Contact and
its e-mail and fax values. I haven't found a way to guarantee a match in code
using any of the Outlook OOM or Redemption objects.

So, you suggestion gets me to the Contact item (unless it's been deleted),
but not to the specific e-mail or fax value within the Contact. Can you help
with that?

Thanks, as always, for your help.


David Lingren

PS

For extra fun with my second (address change) example, open up the MAPIPDL
and click on "Select Members." Try adding the updated e-mail address to the
MAPIPDL. When you click OK, nothing changes. The contact is still in the
MAPIPDL with the old, wrong address and no warning or error is displayed.
 
A deleted contact and a one-off SMTP recipient are the same for all
practical purposes: DL stores both the real entry id (that points to the
contact) and the one-off entry id that embeds the e-mail address.
In case of a on-off entry, the two entry ids are the same.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
 
Back
Top