Use Redemption to read and write Outlook and Exchange properties that are not exposed, are blocked, or are limited in the Outlook Object Model.
Fields collection on RDO objects and Safe*Item objects. The old Redemption.MAPIUtils object remains documented for existing code, but it should not be the first choice for new session-based work.
Use RDOSession and RDO objects when your code owns the MAPI session, needs folder/store/message objects, or runs outside a simple Outlook item wrapper.
Use Safe*Item wrappers when you already have an Outlook item and want a minimal-change way to read or write blocked and missing properties.
Use MAPIUtils only for old code or stateless helper calls against objects you explicitly pass in. Prefer RDOSession for anything that needs a session.
Outlook exposes many item, folder, recipient, and store values through the Outlook Object Model, but not everything is available there. Some properties are Exchange-specific, PST-specific, security-sensitive, too low-level for the object model, or stored as property types the Outlook Object Model does not expose cleanly.
Typical examples include transport headers, sender and recipient address details, message size, icon indexes, named properties, and many provider-specific fields. Outlook 2007 and later include PropertyAccessor, but it still has limitations around certain property types, large binary properties, and properties Outlook treats specially.
Redemption exposes these values through Fields on RDO and Safe* objects, while still letting you use COM-friendly code from VBA, VBScript, .NET, Delphi, C++, and other COM-capable languages.
Redemption.MAPIUtils was the original utility object for raw MAPI property access and other helper operations. It is still documented because existing code uses it and some methods are useful when they operate only on an object you explicitly pass in.
The problem is session ownership. Some MAPIUtils methods need a MAPI session. You can set MAPIUtils.MAPIOBJECT to Application.Session.MAPIOBJECT, but if you do not, MAPIUtils can create or discover a session that is not the Outlook session your code meant to use.
RDOSession makes that choice explicit: set RDOSession.MAPIOBJECT from Outlook when you want to share Outlook's active session, or call one of the Logon methods when your code should open its own session. That makes failures and session boundaries much easier to reason about.
Most Extended MAPI objects are property bags. Messages, folders, stores, recipients, attachments, address book entries, and distribution lists all expose properties through the MAPI IMAPIProp interface.
Every tagged MAPI property is identified by a 32-bit property tag. The upper 16 bits are the property ID, and the lower 16 bits are the property type. For example, PR_SUBJECT_A is 0x0037001E: property ID 0x0037, type PT_STRING8 (0x001E).
Redemption exposes common tags through the MAPITags enumeration. Tools such as OutlookSpy are useful when you need to inspect the actual properties available on a live Outlook object.
| Property type | Hex value | Description |
|---|---|---|
| PT_UNSPECIFIED | 0000 | Reserved; not directly useful from Automation clients. |
| PT_NULL | 0001 | Null value. |
| PT_I2, PT_SHORT | 0002 | Signed 16-bit integer. |
| PT_I4, PT_LONG | 0003 | Signed or unsigned 32-bit integer. |
| PT_R4, PT_FLOAT | 0004 | 32-bit floating-point value. |
| PT_R8, PT_DOUBLE | 0005 | 64-bit floating-point value. |
| PT_CURRENCY | 0006 | Currency value stored as a 64-bit integer. |
| PT_APPTIME | 0007 | Date/time value. |
| PT_ERROR | 000A | 32-bit error value. |
| PT_BOOLEAN | 000B | Boolean value. |
| PT_OBJECT | 000D | Embedded MAPI object; not directly accessible from VB/VBA. |
| PT_I8, PT_LONGLONG | 0014 | 64-bit signed integer. |
| PT_STRING8 | 001E | 8-bit string. |
| PT_UNICODE | 001F | Unicode string. |
| PT_SYSTIME | 0040 | Date/time value. |
| PT_CLSID | 0048 | GUID value. |
| PT_BINARY | 0102 | Byte array. |
Multi-valued properties add 0x1000 to the property type. For example, PT_MV_STRING8 is 0x101E, and PT_MV_UNICODE is 0x101F.
Named properties solve the collision problem for custom or provider-specific data. Instead of choosing a fixed property ID yourself, you provide a GUID plus either a string name or numeric ID. MAPI maps that name to a store-specific property tag.
Outlook user properties use the public strings property set, {00020329-0000-0000-C000-000000000046}. For example, Outlook categories are stored as the named property Keywords in that property set.
Use GetIDsFromNames on an RDO or Safe* object to resolve the property ID, then combine it with the required property type before reading or writing through Fields.
These examples use Safe* objects or RDO objects first. The same low-level values can often be reached through MAPIUtils.HrGetOneProp or HrSetOneProp, but that is the legacy form.
dim sItem, MailItem, PR_SENDER_EMAIL_ADDRESS
set MailItem = Application.Session.GetDefaultFolder(6).Items(1)
set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = MailItem
PR_SENDER_EMAIL_ADDRESS = &H0C1F001E
MsgBox sItem.Fields(PR_SENDER_EMAIL_ADDRESS)
dim Session, MailItem, Msg, PR_SENDER_EMAIL_ADDRESS
set MailItem = Application.Session.GetDefaultFolder(6).Items(1)
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Msg = Session.GetRDOObjectFromOutlookObject(MailItem)
PR_SENDER_EMAIL_ADDRESS = &H0C1F001E
MsgBox Msg.Fields(PR_SENDER_EMAIL_ADDRESS)
dim sItem, MailItem, PR_TRANSPORT_MESSAGE_HEADERS
set MailItem = Application.Session.GetDefaultFolder(6).Items(1)
set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = MailItem
PR_TRANSPORT_MESSAGE_HEADERS = &H007D001E
MsgBox sItem.Fields(PR_TRANSPORT_MESSAGE_HEADERS)
dim sItem, MailItem, PR_CATEGORIES, Categories
const PS_PUBLIC_STRINGS = "{00020329-0000-0000-C000-000000000046}"
const PT_MV_STRING8 = &H101E
set MailItem = Application.Session.GetDefaultFolder(6).Items(1)
set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = MailItem
PR_CATEGORIES = sItem.GetIDsFromNames(PS_PUBLIC_STRINGS, "Keywords")
PR_CATEGORIES = PR_CATEGORIES + PT_MV_STRING8
Categories = sItem.Fields(PR_CATEGORIES)
MsgBox Categories(0)
To set a property, assign through Fields and save the item when the object requires it. This example sets an Outlook icon index on a message.
dim sItem, MailItem, PR_ICON_INDEX
set MailItem = Application.Session.GetDefaultFolder(6).Items(1)
set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = MailItem
PR_ICON_INDEX = &H10800003
sItem.Fields(PR_ICON_INDEX) = 256
sItem.Save
Fields collection and GetIDsFromNames.