How to finalize Outlook Contacts added by Redemption?

R

Remco Happel

Can anyone help me on the following problem:

After adding a new contact and opening + closing it in Outlook XP, I get a dialog box
asking if I want to save changes (no change was made).
After saving (by Outlook) the dialogbox never appear, nothing visible has changed.

Versions used:
Outlook XP (Version 10.0, build:3513, English US, SP1)
Redemption (Version 3.3.0.282)
Visual Basic 6 SP5

I use redemption objects to get a previous specified Outlook folder
Add a new contact by : SafeContactItem = Redemption.Mapifolder.Items.Add("IPM.Contact")
Then I use MAPIUtils.HrSetOneProp for each of the following properties
: FileUnder (save as), Subject, DisplayName, SurName, GivenName,
email1 display (twice, with different propid), email1 address, emailtype.

Last poperty is called by : Call muMT.HrSetOneProp(mySContact, &H8068001E, "SMTP", True)
Where muMT is an instance of MAPIUtils
mySContact is an instance of SafeContactItem
and only this (last) call has bSave=True set.

Did try to finalize the contact by closing de SafeContactItem.
Then get the stored contact with (cdo) 'MAPI.Session.getMessage' into a 'cdoMsg' var.
Calling cdoMsg.ConversationIndex = MAPI.Session.CreateConversationIndex
Call cdoMsg.Update(True, True) 'CDO save message (make permanent + refresh object)

Now releasing all references (and MAPIUtils.Cleanup)
What can I do to fix the problem?

Any help is welcome.
 
H

Henry Gusakovsky

All that stuff happens if Outlook doesn't find all necessary properties in
the contact message.

So use OutlookSpy to identify which ones you've missed to add.



WBR
henry
 
K

Ken Slovak - [MVP - Outlook]

Unless you aren't running any Outlook code at all you can try getting
Message.ID and Message.StoreID after you save the CDO Message and use the
Outlook object model to get and save the item. See if that helps.
 
D

Dmitry Streblechenko \(MVP\)

I am not sure I understand:
1. you create a contact using Redemption
2. Populate its properties using Redemption
3. Save it
4. Open it using Outlook Object Model and display it
5. When closing it, you get a prompt.

this usually means that you did not populate all the required contact
properties in #2 and Outlook added them for you in #4, hence you get the
prompt. Do you set Email1EntryID as well?

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

Remco Happel

Maybe I didn't explain myself correctly so here are some details + code.

After my code has run I switch to Outlook and then open the created/added
contact.
Then, when closing the contact, I get 'Do you wish to save changes'.

I'm trying NOT to use the outlook object model.

Dmitry,
The 'Email1EntryID' (0x806B Email1EntryID PT_BINARY) doesn't exist
until the
contact is saved by outlook (within Outlook).
How do I get this value or force the ID to be created?

My code.

PS:
- myCCDO.mapiSession = a standard CDO Session for wich an instance exists in
myCCDO class.
- This code is a test code to determine an approach that works
so minimal (test)parameters are passed.

- cFld = name of folder to create contact in (not in use anymore)
- cStoreId = storeID of folder to create contact in
- cEntryId = entryID of folder to create contact in
- And for simple testpurpose : Lastname, Firstname and email-adress of
contact to create

- No check on already existing contact yet.

<<This function may contain statements that are not relevant, but trying to
fix the problem....>>

Public Function AddContactByIds(cFld As String, cStoreId As String, cEntryId
As String, _
pLastName As String, pFirstName As String, pEmail1 As String) As Boolean

Dim myMapi As Redemption.MAPIFolder
Dim mySContact As Redemption.SafeContactItem

Dim cdoFld As MAPI.Folder 'cdo.MAPIFolder
Dim cdoMsg As MAPI.Message 'cdo.MAPIMessage
Dim cdoFields As MAPI.Fields 'cdo.MAPIFields

'no on error (testpurposes...)
On Error Resume Next
Set cdoFld = myCCDO.mapiSession.GetFolder(cEntryId, cStoreId)
If Err.Number Then
Call DestroyObjects
Exit Function
End If

If (cdoFld Is Nothing) Then
Call DestroyObjects
Exit Function
End If

Set myMapi = CreateObject("Redemption.MAPIFolder")
myMapi.Item = cdoFld

Set mySContact = CreateObject("Redemption.SafeContactItem")

mySContact.Item = myMapi.Items.Add("IPM.Contact")

Dim muMT As Redemption.MAPIUtils
Set muMT = CreateObject("Redemption.MAPIUtils")

'CdoContact_FileUnder (save as)
Call muMT.HrSetOneProp(mySContact, &H8093001E, Trim(pLastName &
IIf(Len(pFirstName) > 0, ", ", "") &pFirstName), False)

'Subject
Call muMT.HrSetOneProp(mySContact, &H37001E, Trim(pFirstName &
IIf(Len(pFirstName) > 0, " ", "") &pLastName), False)
'DisplayName
Call muMT.HrSetOneProp(mySContact, &H3001001E, Trim(pFirstName &
IIf(Len(pFirstName) > 0, " ", "") & pLastName), False)
'SurName
Call muMT.HrSetOneProp(mySContact, &H3A11001E, Trim(pLastName), False)
'GivenName
Call muMT.HrSetOneProp(mySContact, &H3A06001E, Trim(pFirstName), False)
'email1 display
Call muMT.HrSetOneProp(mySContact, &H808F001E, Trim(pEmail1), False)
'email1 display
Call muMT.HrSetOneProp(mySContact, &H806A001E, Trim(pEmail1), False)
'email1 address
Call muMT.HrSetOneProp(mySContact, &H8069001E, Trim(pEmail1), False)
'emailtype
Call muMT.HrSetOneProp(mySContact, &H8068001E, "SMTP", True)

'Finished with MAPI, cleanup except SafeContact
Set cdoFld = Nothing
Set myMapi = Nothing
Call muMT.Cleanup

'To fully close the contact en re-open : get EntryID.
Dim xEntryId As Variant
Dim intI As Integer
Dim currentId As String
currentId = ""

'Re-create MAPIUtils
Set muMT = CreateObject("Redemption.MAPIUtils")
xEntryId = muMT.HrGetOneProp(mySContact, &HFFF0102)
'Format array to EntryID
For intI = LBound(xEntryId) To UBound(xEntryId)
currentId = currentId & Right(String(2, "0") & Hex(xEntryId(intI)),
2)
Next

'De-reference current
Set mySContact = Nothing
'Get cdoMsg from <currentId>
Set cdoMsg = myCCDO.mapiSession.GetMessage(currentId, cStoreId)

'Finalize ContactPerson object
cdoMsg.ConversationIndex = myCCDO.mapiSession.CreateConversationIndex
Set cdoFields = cdoMsg.Fields
cdoFields.Add CdoContact_FileUnderID, vbLong, &HFFFFFFFF, CdoPropSetID3

'CDO save message (makepermanent + refresh object)
Call cdoMsg.Update(True, True)

'Contact has been added.
'But when, using OUTLOOK XP, openening and closing it (no changes made)
'a dialog ('Save changes dialog') is brought up.

Set cdoFields = Nothing
Set cdoMsg = Nothing

'To be sure, kill redemption MAPI connection
Call muMT.Cleanup
Set muMT = Nothing

AddContactByIds = True
End Function
 
D

Dmitry Streblechenko \(MVP\)

Yep, Email1EntryID is the problem then - you can construct a one-off entry
id using the address, address type and name. See "One-Off Entry Identifiers"
on MSDN or look at any AB entry id in OutlookSpy (e.g. click IMessage and
select PR_SENDER_ENTRYID in a message that came from an SMTP sender).
Essentially you will need to concatenate a fixed prefix with the address,
name and address type separated by 0x0.

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

Remco Happel

Thank you Dmitry,

It works!

Still had some problems on other systems but solved that.
(using GetIDsFromNames for the ... named properties)

Thanks again.
 
Top