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);

}