Working with Multivalued Properties
Topic Last Modified: 2006-06-12
Properties for items in the Exchange store can have multiple values. In this case, you set or retrieve the property using an Array (SAFEARRAY). Even if the multivalued property has only one value, you still use an Array.
Each value in the array must be of the same type. For example, a property can be a multivalued array of Strings (string or BSTR) or Longs (i4 or long), but not both strings and integers.
The following example demonstrates how to set and retrieve multivalued properties for items.
Note
To access the global schema of an application or a public store, use The ##SCHEMAURI## Macro.
Example
VBScript
Example
' Assume URL is defined and points to a folder.
Const adModeReadWrite = 3
Dim Rec
Dim Conn
Set Conn = CreateObject("ADODB.Connection")
Set Rec = CreateObject("ADODB.Record")
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open URL
Rec.Open URL, Conn, adModeReadWrite
Dim Flds
Set Flds = Rec.Fields
Dim rgBaseSchema
rgBaseSchema = Flds("urn:schemas-microsoft-com:exch-data:baseschema").Value
' ...
Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value = _
Array("urn:content-classes:item", "urn:schemas-domain-tld:content-classes:special")
Flds.Update
Visual Basic
' Reference to ActiveDs Type Library
' Reference to ActiveX Data Objects 2.5 Library
Sub MultiValPropsExample()
Dim sUrl As String
Dim Info As New ADSystemInfo
Dim InfoNT As New WinNTSystemInfo
sUrl = "http://" & InfoNT.ComputerName & "." & Info.DomainDNSName & _
"/public/test_folder3/"
Dim Conn As New ADODB.Connection
Dim Rec As New ADODB.Record
Conn.Provider = "ExOLEDB.DataSource"
Conn.Open sUrl
Rec.Open sUrl, Conn, adModeReadWrite
Dim Flds As ADODB.Fields
Set Flds = Rec.Fields
Dim rgExpectedContClass As Variant
rgExpectedContClass = Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value
If IsArray(rgExpectedContClass) Then
For I = LBound(rgExpectedContClass) To UBound(rgExpectedContClass)
Debug.Print rgExpectedContClass(I)
Next I
' ...
Else
Debug.Print "Error...VarType for returned VARIANT:"
Debug.Print VarType(rgExpectedContClass)
End If
Dim rgCCs(2) As Variant
rgCCs(0) = "urn:content-classes:item"
rgCCs(1) = "urn:schemas-domain-tld:content-classes:special"
Flds("urn:schemas-microsoft-com:exch-data:expected-content-class").Value = rgCCs
Flds.Update
End Sub
C++
#import <msado15.dll> no_namespace
#import "c:\program files\common files\microsoft shared\cdo\cdoex.dll" no_namespace
#include <iostream.h>
void setBaseSchema(bstr_t sFolderUrl) {
_RecordPtr Rec(__uuidof(Record));
_ConnectionPtr Conn(__uuidof(Connection));
Conn->Provider = "ExOLEDB.DataSource";
try {
Conn->Open(sFolderUrl, bstr_t(), bstr_t(), -1);
}
catch(_com_error e) {
cout << "Error opening connection." << endl;
//..
throw e;
}
wchar_t* url1 = L"https://server/public/test_folder2";
wchar_t* url2 = L"https://server/public/test_folder3";
wchar_t* url3 = L"https://server/public/non_ipm_subtree/Schema";
VARIANT vVal;
VariantInit(&vVal);
vVal.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAY* psa = NULL;
psa = SafeArrayCreateVector(VT_VARIANT, 0, 3);
if(psa == NULL) {
// handle error here.
}
VARIANT* pVal;
HRESULT hr = S_OK;
hr = SafeArrayAccessData(psa, (void**)&pVal);
if(FAILED(hr)) {
// handle error
}
VariantInit(&(pVal[0]));
pVal[0].vt = VT_BSTR;
pVal[0].bstrVal = SysAllocString(url1);
VariantInit(&(pVal[1]));
pVal[1].vt = VT_BSTR;
pVal[1].bstrVal = SysAllocString(url2);
VariantInit(&(pVal[2]));
pVal[2].vt = VT_BSTR;
pVal[2].bstrVal = SysAllocString(url3);
SafeArrayUnaccessData(psa);
vVal.parray = psa;
try {
Rec->Open(sFolderUrl,
variant_t((IDispatch*)Conn,true),
adModeReadWrite,
adFailIfNotExists,
adOpenSource,
bstr_t(),
bstr_t());
}
catch(_com_error e) {
cout << "Error opening item" << endl;
//..
}
FieldsPtr Flds;
Flds = Rec->Fields;
FieldPtr Fld;
Fld = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"];
Fld->Value = vVal;
SafeArrayDestroy(psa);
VariantClear(&vVal);
psa = NULL;
try {
Flds->Update();
}
catch(_com_error e) {
cout << "update failed" << endl;
cout << e.Description() << endl;
}
// Now, read the props back and print the values...
variant_t vBaseSchema;
vBaseSchema = Flds->Item["urn:schemas-microsoft-com:exch-data:baseschema"]->Value;
if( ! (vBaseSchema.vt == (VT_ARRAY | VT_VARIANT))) {
cout << "Unexpected..." << endl;
// handle error
}
hr = SafeArrayAccessData(vBaseSchema.parray, (void**)&pVal);
if(FAILED(hr)) {
cout << "access data failed!!" << endl;
}
cout << "Set the baseschema property for the folder at \r\n " << sFolderUrl;
cout << " \r\nto the following URLS: " << endl;
cout << bstr_t(pVal[0].bstrVal) << endl;
cout << bstr_t(pVal[1].bstrVal) << endl;
cout << bstr_t(pVal[2].bstrVal) << endl;
SafeArrayUnaccessData(vBaseSchema.parray);
}