本章說明使用CDO建立應用程式的核心技術,著重於如何使用CDO存取與修改Web儲存系統中的資源,也討論如何使用CDO管理資料夾與連絡人。章節內容包含:
- CDO概觀
- 開始使用CDO
- 了解並使用IDataSource介面
- 資料夾的處理
- 連絡人資訊的處理
CDO概觀
CDO是一個可以用來建立用途廣泛的協同作業應用程式的技術,完成諸如:傳送與接收電子郵件、行事曆、連絡人管理、工作流程以及Exchange管理的應用程式。CDO是設計以藉由提供一些方法與屬性來輔助提升ADO的功能,特別是如傳送郵件與安排約會之類的協同作業的處理。如同ADO,CDO是一個伺服器架構(server-based)的API。
與之前版本的CDO不同的是,CDO for Exchange必須安裝於以Microsoft Windows 2000 Advanced Server為系統平台並且安裝Exchange 2000伺服器的電腦上,因為CDO需要Exchange OLE DB(ExOLEDB)provider。CDO於在伺服器上執行程式碼的應用程式中有最佳的表現,包含以Exchange伺服器架構的應用程式,比如:事件接收與伺服器管理工具、Web架構(Web-based)使用ASP(Active Server Pages)技術的應用程式。本節說明三種不同的CDO物件模組並討論個別的用法。
說明
您可以繼續在用戶端應用程式中使用先前版本的CDO來存取Exchange 2000伺服器,如:CDO 1.2與CDO 1.21。
ADO vs. CDO
雖然可以單純只使用ADO或只使用CDO來建立Web儲存系統解決方案,您可能會希望只使用其中之一作為主要物件,而不需要再搭配另一個物件來開發。事實上ADO與CDO是設計來相輔相成而非相互對立,並且兩者都使用ExOLEDB。表示在使用這兩個物件模組時,可以在Web儲存系統中使用相同的技術來將URL與資源做結合。因此,應該使用哪一個物件模組,取決於您需要哪一方面的功能需求。
ADO 2.5於瀏覽、搜尋與設定Web儲存系統中的資源有最佳的表現,還能專門處理一般資源修改的工作,如複製與移動record。
當需要建立協同作業架構的應用程式時,便應該使用CDO。CDO是建立協同作業主要的物件模組,因為CDO具有專門設計用來建立電子郵件、行事曆與連絡人管理系統的物件模組。您可以使用CDO建立伺服器管理工具與複雜的路由(routing)系統,也可以輕易地使用CDO物件模組來設定物件特定的屬性。
CDO物件模組
CDO並不是被封裝為一個單獨的物件模組,相反地,CDO包含了三個不同的物件模組,每一個都有其特定的用途,您可以單獨或同時使用這些物件模組。表5-1列出這三個物件模組以及與其相關的DLL名稱。安裝Exchange 2000時,預設也會將這三個CDO DLL安裝於系統中,如果此三個物件模組沒有安裝於系統中,您可以重新執行安裝程式,選擇Messaging and Collaboration選項。
表5-1 CDO for Exchange的DLL |
DLL | 檔案名稱 |
---|---|
CDO for Exchange 2000 Server | Cdo.dll |
CDO for Exchange Management Objects | Cdoexm.dll |
CDO Workflow for Exchange | Cdowf.dll |
了解CDO for Exchange 2000伺服器的物件模組
CDO for Exchange 2000伺服器是最主要且最常用的CDO物件模組,此物件模組包含了一些協同作業應用程式中最常見的核心物件與介面,例如:電子郵件應用程式、連絡人管理系統以及行事曆應用程式。除此之外,您也可以使用CDO for Exchange 2000伺服器的物件模組來建立與設定Web儲存系統中的資料夾。最上層(top-level)的CDO物件常用來建立以下幾種解決方案:
- 資料夾(Folder):在信箱存放區或公用存放區的容器。
- 人員(Person):Web儲存系統資料夾中的連絡人類型的資訊,或是Active Directory中的使用者或連絡人物件。
- 郵件(Message):電子郵件。
- 約會(Appointment):已排程的約會或會議。
- 行事曆訊息(Calendar Message):會議邀請。
- 收件者(Addressee):任何型式的電子郵件收件者或會議邀請的收件者。
- 出席者(Attendee):包含於約會或會議中的人員。
所有最上層物件都有兩個重要的共同介面(interface),提供典型的物件設定與檔案輸入輸出(Input/Output)的功能。IConfiguration介面用來定義可應用於多個物件的行為模組(behavior model),每個CDO物件都公開IDataSource介面,可以用來管理、存放與儲存資料。
除了這兩個重要的介面以外,有些CDO物件也使用其他介面針對特別的工作提供特定的功能。於郵件應用程式中,使用IBodyPart介面存取MIME郵件的部分內容,如標頭(header)或HTML區塊(body)。同樣地,您可以使用ICalendarPatrs介面修改會議邀請的行事曆部分,以及使用IRecurrencePatterns與IExceptions介面來安排會議。
如果使用Microsoft Visual Basic建立COM元件,並欲使用早期連結(early binding),則要設定一個參照(reference)至Exchange 2000的Microsoft CDO函式庫,此函式庫是以CDO出現於物件瀏覽器(Object Browser)當中。
了解CDO for Exchange Management Objects的物件模組
先前所提到的Exchange 2000管理物件,CDO for Exchange Management Objects是由用來建立以及管理Exchange信箱與Exchange伺服器元件的類別(classes)與介面所組成。伺服器自行管理其運作非但不重要的工作,您可能還會發現自己時常使用這些物件撰寫程式碼管理Exchange的收件者與信箱。針對這類型的應用程式,應該使用的物件是:
- IMailRecipient:針對使用者指定電子郵件如何傳送與管理,此物件也可以使連絡人與資料夾不需要信箱便可接收電子郵件。
- IMailboxStore:指定如何建立、移動與刪除Exchange信箱,以及如何管理可使用信箱的收件者其可用來管理的屬性。
雖然最常使用Exchange System Manager此嵌入於MMC的嵌入式管理單元來管理Exchange伺服器,但您還是可能會決定開發自己的Exchange伺服器管理工具。例如:或許您想要開發Web架構的伺服器管理工具。CDO for Exchange Management Objects也提供讓您可以整體地管理伺服器的物件,這些狀況可用的最上層物件有:
- ExchangeServer:管理Exchange 2000伺服器與傳回基本資訊,如伺服器類型與版本。
- FolderTree:管理伺服器中的資料夾樹狀結構,包含任何副本。
- StorageGroup:管理儲存群組,用來組織信箱存放區與公用存放區。
- MailboxStoreDB:管理單一使用者的信箱存放區,可以使用此物件來連結、移動或中斷連結信箱存放區,並傳回有關存放區資料庫的基本資訊。
- PublicStoreDB:建立、管理與刪除公用存放區,並傳回有關存放區資料庫的基本資訊。
如果使用Microsoft Visual Basic建立COM元件,並欲使用早期連結,則要設定一個參照至Exchange管理的Microsoft CDO函式庫,此函式庫是以CDOExM出現於物件瀏覽器當中。
了解CDO Workflow for Exchange物件模組
CDO Workflow for Exchange物件模組,是由用來建立以及執行工作流程與路由應用程式的類別(classes)與介面所組成。建立工作流程應用程式有二種方式有二種方式:使用Workflow Designer for Microsoft Exchange 2000 Server,或使用自行建立工作流程事件流程與事件接收的方式。對大部分的開發人員而言,Workflow Designer已提供足夠的功能與彈性來滿足所有應用程式開發的需求,使用Workflow Designer,您便不需要大部分的工作流程物件,只有撰寫回應各式各樣工作流程動作的script時,才需要使用到這些物件。在script中最有可能使用到的物件如下:
- IWorkflowSession:提供工作流程引擎、動作的script與所處理的工作流程項目(ProcessInstance)之間的執行期(run-time)通訊。
- IWorkflowMessage:建立工作流程處理中要傳送給收件者的通知郵件。
- AuditTrailEventLog:於應用程式記錄檔(log)中,建立有關工作流程事件動態的項目(entries)。
假使Workflow Designer無法提供您所要達成的設計功能,那就要自行建立事件接收,雖然使用這種方法可以讓應用程式獲得更多的彈性與控制,然而您也要承擔額外的責任。您必須建立工作流程應用程式的每一部份的外觀,並且要使用工作流程物件函式庫中幾乎所有的物件。此外,除了先前所列的物件與介面之外,您也要熟悉下列物件:
- ProcessDefinition:定義工作流程中的邏輯,包含狀態與動作。
- ProcessInstance:控制、記錄與監視移動於工作流程處理之間、個別獨立的工作流程項目的狀態。
如果使用Microsoft Visual Basic建立工作流程工具與事件接收,並欲使用早期連結,則要設定一個參照至Exchange的Microsoft CDO Workflow函式庫,此函式庫是以CDOWF出現於物件瀏覽器當中。
開始使用CDO
CDO for Exchange使用了COM的類別與介面的標準。本節會介紹一些重要的概念,假使您是一位Visual Basic的開發人員,可能會對這些概念相當熟悉。本節也探討使用CDO物件模組撰寫程式的核心技術。
由類別建立物件
CDO由多種COM的類別所組成,是用來建立新物件的基礎。當物件被建立的時候,這些類別會決定物件標準的預設功能。例如CDO的Message類別就是用來定義新的Message物件,每個Message物件都有相同的標準功能,允許物件被傳送與接收。您可以設定既有屬性來自訂每一個物件,或為物件新增您自訂的屬性。Web儲存系統也允許您自行定義類別。有關自訂類別更多的詳細資訊,請參閱
如果使用Visual Basic由CDO COM的類別建立物件,便可以利用早期連結的好處,只要設定參照至適當的函式庫,然後於程式碼中使用適當的類別來宣告物件變數,再使用New關鍵字建立一個類別的執行個體(instance)。下列範例程式碼建立CDO Message物件:
Dim msg As CDO.Message Set msg = New CDO.Message
如果使用Microsoft Visual Basic Scripting Edition(VBScript)與ASP,在宣告變數時便無法使用New或As關鍵字。相反地,宣告變數時不能使用物件型態來宣告,必須使用Server.CreateObject方式來建立新物件,並傳遞一個字串舉出類別的名稱。要使用VBScript與ASP技術建立一個新的Message物件,其程式碼如下:
Dim msg Set msg = Server.CreateObject("CDO.Message")
現在您可以存取此類別預設介面中的屬性與方法,以及任何該類別公開的其他介面。
與所有物件導向的程式語言一樣,在使用完物件變數之後,必須釋放物件變數的程式碼所佔用的記憶體資源。設定物件變數為Nothing以釋放先前分配給變數的記憶體資源,程式碼如下:
Set msg = Nothing
使用介面
與COM類別不同的是,介面不為物件做定義。相反地,介面定義了一個由屬性與方法封裝在一起的集合。有些介面專屬某些類別,而其他介面定義了一般的功能。藉由封裝屬性與方法的方式,介面可以輕易地在事先定義的類別與自訂的類別之間被分享。
類別通常有多個與其相關連的介面,包含一個預設(default)的介面,此預設介面擁有類別既定的預設功能。預設介面與該物件呈現的名稱幾乎相似,只是在物件名稱之前多了一個字母I,表示這是一個相對於類別物件的介面。例如,Person類別有一個管理所有屬性與方法的IPerson介面,特別用來定義與管理連絡人類型的資訊。此預設介面是由其所屬物件直接公開,也就是您可以由物件直接呼叫屬性與方法。您可以直接呼叫Person物件的e-mail屬性,程式碼如下所示:
Dim prs As CDO.Person Set prs = New CDO.Person prs.Email = "someone@domain.com"
除了預設介面以外,大部分的類別至少使用一個以上的其他介面,這些預設介面也會被其他類別所使用。例如,IDataSource介面包含了可由CDO物件及Web儲存系統開啟與儲存資料的方法,因為每個最上層的CDO類別都需要此功能,如Person與Message物件實作(implement)了一個IDataSource介面。當參照介面之後才能存取其屬性與方法,您可以輕易地經由呼叫相關屬性來達成。IDataSource介面經由DataSource被存取,程式範例如下:
Dim dsrc As IDataSource Set dsrc = prs.DataSource
有些介面並沒有用以參照的相關屬性。例如,CDOEXM的IMailRecipient介面是用來管理個人或資料夾的電子郵件,但不能使用一致的屬性名稱存取此介面。
存取IMailRecipient介面的方法取決於是使用Visual Basic或VBScript。若使用Visual Basic,您可以宣告物件變數作為適當的介面,然後藉由將介面物件變數指向物件公開的介面,自動完成參照介面的動作。下列範例程式碼便是將IMailRecipient介面參照至一個資料夾。
Dim fld As CDO.Folder Dim rcp As CDOEXM.IMailRecipient Set rcp = fld
若使用VBScript,則不能替變數預先宣告資料型態。因此您必須使用GetInterface方法來存取介面,幾乎每個CDO物件都公開用以存取介面的GetInterface方法。下列範例程式碼便是使用VBScript存取IMailRecipient介面。
Set rcp = fld.GetInterface("IMailRecipient")
存取結構描述屬性
雖然ADO需要使用Fields集合物件才能更改結構描述屬性,但CDO提供了一個更簡單的方式,許多比較一般的結構描述屬性都可經由CDO屬性來存取。例如,您可以存取Person物件中的urn:schemas:contacts:HomePhone結構描述屬性,其程式碼如下:
prs.HomePhone = "555-555-0101"
對結構描述屬性而言並沒有相等的CDO屬性,您必須使用Fields集合物件,因為是實際的ADOFields集合物件,因此具有相同的屬性與方法。欲存取集合物件中的特定屬性,要傳遞完整且合格的結構描述屬性名稱,若有相同的CDO相關常數(constant)也要一併傳遞。這些常數以 cdo 開頭且包含於CDO物件函式庫中,您可以使用這些常數以省去傳遞完整屬性名稱的麻煩,使用CDO常數來傳遞時,其名稱並不需要加上引號。下列範例程式碼設定urn:schemas:contacts:FTPSite的屬性:
prs.Fields(cdoFtpSite)="somearchive.edu"
提示
要參考完整的常數清單,在Visual Basic或Microsoft Office產品的Visual Basic編輯器裡設定參照CDO物件函式庫,使用物件瀏覽器(Object Browser)來瀏覽所有常數。
假使您要存取的結構描述屬性沒有可用的CDO屬性或常數,就必須傳遞完整且合格的結構描述屬性名稱給Fields集合物件。例如,下列範例程式碼也是存取與上個範例程式碼相同的屬性,但是其傳遞合格的結構描述屬性名稱作為字串常值(string literal)。
prs.Fields("urn:schemas:contacts:ftpsite") = "somearchive.edu"
若程式碼中使用很多合格的結構描述屬性名稱,程式碼看起來可能會像加密過的文件。重要的是,因為屬性名稱有區分大小寫,而且每次使用到結構描述屬性都要鍵入完整的名稱,所以程式碼很容易就會有錯誤的發生。因為如此,假使應用程式中使用的屬性不存在CDO屬性或沒有建立結構描述常數,您便應該為應用程式定義自己的常數。
使用URL
與ADO一樣,CDO也是仰賴URL以及ExOLEDB provider來存取Web儲存系統中的資源,所要被存取的資源必須以完整的資料夾路徑與顯示的名稱(DAV:displayname),建構正確的URL位址。假使您正在開啟的項目如連絡人或電子郵件,項目的來源並不明確,那就在URL之後加上 .eml的附檔名。資料夾路徑或項目的顯示名稱中有空白字元,在URL中也必須保留名稱中的任何空白字元。例如,假使於Applications樹狀結構中建立了Zoo Management應用程式,您便要使用下列URL存取Staff資料夾:
File://./backofficestorage/Applications/Zoo Management/Staff/
當開啟資料夾時,URL最後的「/」斜線符號並非必需的,但是加上斜線符號是撰寫程式的一個好習慣。在指向資料夾的URL最後面加上斜線符號,可以很快地區分URL指的是一個資料夾或是一個項目。存取資料夾中的連絡人可以使用如下列所示的URL:
File://./backofficestorage/Applications/Zoo Management/Staff/Amy Luehmann.EML
有關URL使用方法的更多資訊,請參閱第二章〈Exchange與Web儲存系統〉 。有關在ExOLEDB中使用URL的更多資訊,請參閱 第四章〈ActiveX Data Object與Exchange〉 。
說明
CDO也支援相對的(relative)URL用法。
了解並使用IDataSource介面
IDataSource介面是使用CDO存取Web儲存系統中資源的關鍵,所有的CDO物件經由DataSource屬性公開IDataSource介面,DataSource屬性可以用來在Web儲存系統中開啟資源、偵測與儲存資源的變更,以及建立新資源。
本節列出IDataSource的屬性與方法;說明IDataSource介面如何運作;告訴您如何使用CDO開啟資源、偵測與儲存資源的變更,以及使用CDO建立新資源;也說明如何從其他物件開啟CDO物件,並可以檢查項目是否存在。
IDataSource介面的屬性與方法
不管您要使用CDO來達成什麼目的,您一定會使用到IDataSource介面。表5-2列出IDataSource介面公開的屬性與方法。
表5-2 IDataSource介面公開的屬性與方法 |
名稱 | 類型 | 傳回值 | 說明 |
---|---|---|---|
ActiveConnection | Property | Connection | 假使資源連結至物件,便傳回作用中的連線物件(唯獨)。 |
IsDirty | Property | Boolean | 判斷本機的資料副本是否變更。 |
Source | Property | Unknown | 傳回目前連結的物件(唯獨)。 |
SourceClass | Property | String | 傳回最初用來開啟資料來源的的介面名稱(唯獨)。 |
SourceURL | Property | String | 傳回目前連結物件的URL(唯獨)。 |
Open | Method | N/A 1 | 為現存資源開啟資料來源。 |
OpenObject | Method | N/A | 從其他物件開啟CDO物件。 |
Save | Method | N/A | 儲存變更至現存的資源。 |
SaveTo | Method | N/A | 以指定名稱儲存資料來源至指定資源的URL。 |
SaveToContainer | Method | N/A | 在容器中儲存資料來源。 |
SaveToObject | Method | N/A | 儲存資料來源至其他物件。 |
1無法使用
IDataSource介面如何運作
當使用CDO開啟一個資源時,並非動態地連線到Web儲存系統,而是將資料由Web儲存系統中複製一個副本到本機的CDO物件。所以實質上您會有兩份資料:一份在Web儲存系統中,另一份在CDO物件中。使用CDO物件屬性與方法對資料所做的任何改變,是本機上的資料副本而不是Web儲存系統中的原始資料,Web儲存系統中的資料會保持原始內容,直到使用IDataSource的儲存方法明確地指定要對資料做變更,Web儲存系統中的資料才會以更新後的值取代。假使沒有呼叫其中任何一個儲存的方法,所有已變更的資料副本將會遺失,Web儲存系統的資料將維持不變。
當建立一個新資源時也是相同道理,在呼叫任一個儲存方法之前,資源不會被儲存於Web儲存系統中。此外,如果經由Fields集合物件來變更結構描述屬性,您也必須獨立呼叫在儲存方法中的更新(Update)方法。因為Update方法只會改變本機的資料副本,所以在呼叫IDataSource儲存方法之前必須先呼叫Update方法。
使用CDO開啟資源
您可以使用適當CDO物件中的DataSource.Open方法,DataSource.Open是一個以ADO的Record.Open方法為基礎的開啟資源方法。然而CDO並不支援所有的參數(parameters),CDO使用的Open方法其語法如下:
Sub Open( SourceURL As String [, ActiveConnection As Object] [, Mode As ConnectModeEnum])
參數用法:
SourceURL
要被開啟的資源的URL,例如一個資料夾或一個資料夾中的項目,這是唯一的必要引數(argument)。
ActiveConnection
選擇性引數,指定要用來開啟資源的連線。若使用既存連線便不設定其值。
Mode
選擇性列舉引數,指定record應該如何被開啟。可以使用下列常數:adModeRead、adModeReadWrite、adModeRecursive、adModeShareDenyNone、adModeShareDenyRead、adModeShareDenyWrite、adModeShareExclusive、adModeUnknown或adModeWrite。
使用Open方法時,若只有指定URL引數,則資源會以唯讀模式被開啟。欲開啟資源編輯時,必須傳遞adModeReadWrite作為Mode的引數。
說明
本章所列的程式碼都是可執行的,您可以在隨書所附光碟上的微軟Visual Basic專案CH_05.vbp中找到。如果您要執行範例程式,必須先將Zoo Management這個範例程式安裝在您的Exchange 2000伺服器上。有關安裝資訊,請參閱
〈本書簡介〉 。此外,範例程式中經常呼叫一個名為GetStorageName的函式,此函式會傳回程式執行的網域名稱,有關此函式的資訊,請參閱第八章〈與Active Directory互動〉 。
範例程式5-1說明如何使用DataSource.Open方法以唯讀模式開啟一個資源,此程序建立一個新的CDO Folder物件,並且經由傳遞資料夾的URL給Folder物件的DataSource.Open方法開啟資料夾。因為沒有傳遞任何其他參數,此資料夾便是以唯讀模式被開啟。然後程式碼會列舉出資料夾的屬性,並且傳回其名稱與值,假使屬性是單一值(single-valued),則傳回屬性名稱與屬性質,若屬性是多重值(multi-valued),則傳回屬性名稱與字串 MULTIVALUED 。
範例程式5-1:使用CDO開啟Web儲存系統中的資源
Sub OpenAResource_CDO() ' Return info about a folder Dim urlFolder As String Dim fd As ADODB.Field urlFolder = GetStorageName & "Applications/Zoo Management/" ' If you are using VBScript, use this With: ' With CreateObject("cdo.folder") With New CDO.Folder ' Open the folder .DataSource.Open urlFolder ' Enumerate through the properties For Each fd In .Fields If Not IsArray(fd.Value) Then ' If the property is single valued, ' return the name and the current value Debug.Print fd.Name, fd.Value Else ' If the property is multi-valued, ' Identify it as such ' For info on enumerating multivalued properties, ' See Chapter 4 for ADO and Chapter 13 for XML Debug.Print fd.Name, "〔MULTIVALUED〕" End If Next End With ' Clean up Set fd = Nothing End Sub
偵測與儲存變更
資源被開啟並呈現於用戶端應用程式之後,使用者可能有修改資料的需求。在使用者變更資源內容後,所有修改過的資料應該藉由呼叫Save方法存回Web儲存系統。然而,若沒有對資源做任何變更,則不需要呼叫Save方法。IDataSource介面的DataSource.IsDirty屬性,可以用來判斷是否有修改過本機所開啟的資料來源。
DataSource.IsDirty屬性是用來判斷本機的資料副本是否被修改過的布林(Boolean)值。當CDO物件開啟資源後,會有兩份一模一樣的資料存在:原始的資料會在Web儲存系統中,另一份資料會被快取(cached)存於本機的CDO物件中。當資訊初始快取時,本機的資料副本會被清除,並且DataSource.IsDirty屬性會傳回False值。當用戶端更新時,本機的資料副本會視為被更新過(dirty),而DataSource.IsDirty屬性會被設為True值。DataSource.IsDirty屬性會在下列任何一個狀況發生時被設為False值:
- 呼叫Save方法(參考下段文字內容)將本機修改完的資料副本儲存回Web儲存系統。
- CDO物件變數參照的本機資料副本被設為Nothing。
- CDO物件變數參照的本機資料副本被連結至不同資源。
假使用戶端確實修改了資料,而資料也需要被儲存,則必須呼叫DataSource.Save方法儲存已被變更的物件,DataSource.Save方法不需要引數。在完成物件的編輯並確定要將其變更儲存至Web儲存系統時,便需要呼叫DataSource.Save方法,若沒有呼叫此方法,則所有的變更將會遺失,原來Web儲存系統中的資料會保持原狀。此方法並非使用於從未被儲存過的物件(新物件)。
下列範例程式碼展示如何使用DataSource.IsDirty屬性以及DataSource.Save方法。您幾乎可以使用此範例程式碼於任何程序中偵測資料是否被修改,DataSource.IsDirty屬性用來判斷本機CDO物件是否被變更,如果傳回屬性為True,則程式碼使用DataSource.Save方法儲存變更過的資料,若資料沒有被修改過,則不會有任何動作發生。
If cdoObject.DataSource.IsDirty Then 'Save changes to the source. cdoObject.DataSource.Save End If
注意
DataSource.IsDirty屬性只檢查本機的這份資料是否被變更,並不會判斷其他的用戶端應用程式是否修改Web儲存系統中的原始資料。舉例來說,假使第一個使用者的應用程式開啟一個資源來作處理,另一個應用程式隨後又開啟相同的資源,而第二個應用程式對資源所做的修改動作,並不會反應至第一個應用程式本機的資料副本,也就是說使用者可能一不小心就覆寫其他使用者所做的變更。想要進一步控制這一類狀況的發生,可以使用伺服器事件(server events)監控伺服器中資源的變更狀況。有關使用以及建立Web儲存系統事件(Web Storage System events)更多的相關資訊,請參閱 第九章〈使用Web儲存系統事件〉 。
使用CDO建立新物件
欲在Web儲存系統資料夾中建立新資源,可以先定義物件再呼叫DataSource.SaveTo方法或DataSource.SaveToContainer方法儲存至Web儲存系統。本章先前有提到,若使用Fields集合物件來設定任何屬性值,必須要在呼叫儲存方法之前先呼叫Fields.Update方法。本節說明如何藉由儲存至URL與儲存至容器建立新資源。
儲存至URL
在Web儲存系統中建立新資源的一個方式,就是為資源建立URL然後再將資訊儲存至此URL,DataSource.SaveTo方法可以讓您指定所建立資源的URL。換言之,假使資源是既有的資源,必須針對其實際位置精確地建立URL,包含資源的資料夾路徑與DAV:displayname。
提示
建立資料夾時,在其URL最後加上斜線符號(/),建立項目時,在其URL之後加上附檔名 .eml。這是一個習慣而非正式的標準,可以幫助您節省往後區別URL是表示資料夾或項目的時間。
DataSource.SaveTo方法使用的參數與DataSource.Open方法相似,CDO的DataSource.Open方法其語法如下:
Sub SaveTo( SourceURL As String [, ActiveConnection As Object] [, Mode As ConnectModeEnum] [, CreateOptions As RecordCreateOptionsEnum])
參數用法:
SourceURL
要被儲存的資源的URL,例如一個資料夾或一個資料夾中的項目,這是唯一的必要引數(argument)。若建立的資源是項目,則其URL應該包含附檔名 .eml。
ActiveConnection
選擇性引數,指定要用來開啟資源的連線。若使用既存連線便不設定其值。
Mode
選擇性列舉引數,指定record應該如何被開啟。可以使用下列常數:adModeRead、adModeReadWrite、adModeRecursive、adModeShareDenyNone、adModeShareDenyRead、adModeShareDenyWrite、adModeShareExclusive、adModeUnknown或adModeWrite。
CreateOptions
選擇性列舉引數,指定資源如何被建立。欲覆寫相同URL的既有資源,設定其為常數adCreateOverwrite,SaveTo方法的CreateOptions參數並不支援其他常數。
範例程式5-2展示如何使用DataSource.SaveTo方法在Web儲存系統資料夾中建立一個新資源,在此之前新資源的URL已被建立。本範例中因為程式碼建立的是項目,所以URL被加上附檔名 .eml。接著此程序建立一個新的CDO Person物件,並設定一些相關屬性,包含一個只能經由Fields集合物件存取的屬性。最後此程序呼叫DataSource.SaveTo方法並傳遞URL作為新連絡人的URL。
範例程式5-2:在資料夾中建立新的連絡人
Sub CreateAResourceAtAURL() ' Create a new contact in ' a Web Storage System folder ' using a specific URL. Dim urlStaffMember As String urlStaffMember = GetStorageName & _ "Applications/Zoo Management/Staff/Amy Luehmann.EML" ' If you are using VBScript, use this With: ' With CreateObject("cdo.person") With New CDO.Person ' Set some of the basic contact properties .FirstName = "Amy" .LastName = "Luehmann" .HomeCity = "Redmond" .HomeState = "Washington" .Email = "amy@domain.com" ' You can use one or the other ' of the following: '.Fields("urn:schemas:contacts:ftpsite") = "somearchive.edu" .Fields(cdoFtpSite) = "somearchive.edu" 'Save the changes made through the Fields collection .Fields.Update 'Save the information to the URL and overwrite any existing contact .DataSource.SaveTo urlStaffMember, , , adCreateOverwrite End With End Sub
說明
假使範例程式5-2中的程式碼沒有傳遞常數adCreateOverwrite給DataSource.SaveTo方法,則當連絡人已經存在時,此程序會執行失敗。為避免這種狀況發生,您必須在嘗試儲存資源之前,先確定所要用來儲存的URL與實際的URL中,資源是否已經存在。有關如何驗證URL的相關資訊,請參閱本章稍後的〈檢查資料夾或項目是否存在〉 一節。
儲存至容器
DataSource.SaveToContainer方法提供您將資源儲存至Web儲存系統的另一個選擇,可以讓您不需在URL中為資源命名便將其儲存至指定的資料夾。DataSource.SaveToContainer方法看起來與DataSource.SaveTo方法很像,兩者擁有相同的參數,但在URL參數的使用上並不相同,DataSource.SaveToContainer方法需要的URL是建立項目的資料夾所在位置。其URL不包含新項目的DAV:dispalyname值,而是在儲存資源時,由Exchange自動產生新項目的DAV:dispalyname值。
DataSource.SaveToContainer方法使用在行事曆中建立約會時更能發揮其作用,因為在行事曆容器中時常有相同的約會名稱。例如,若使用DataSource.SaveTo方法在行事曆中建立一個名為「牙醫師」的約會,當再使用DataSource.SaveTo方法建立另一個「牙醫師」的約會時,將會有錯誤發生。假使您選擇覆寫的參數,則第一個「牙醫師」約會將會被取代,甚至是第二個發生於六個約之後的「牙醫師」約會也會被取代。然而,使用DataSource.SaveToContainer方法可以確定相同名稱的新約會項目不會取代既有的約會。
範例程式5-3說明如何在行事曆中建立新的約會,在程式碼建立約會並設定相關屬性之後,呼叫DataSource.SaveToContainer方法並傳遞該項目的行事曆資料夾位置給URL引數,DAV:displayname屬性由CDO以及Exchange指定。
範例程式5-3:建立新資源時自動產生DAV:displayname
Sub SaveToContainer() ' Save the appointment to the container ' Exchange will provide the display name Dim urlSurgeryFld As String urlSurgeryFld = _ GetStorageName & "Applications/Zoo Management/Surgery/" ' If you are using VBScript, use this With: ' With CreateObject("cdo.appointment") With New CDO.Appointment ' Add the time zone information .Fields(cdoTimeZoneIDURN) = cdoPacific .Fields.Update .StartTime = "10/9/2001 1:30:00 PM" .EndTime = "10/9/2001 2:30:00 PM" .Subject = "Tooth extraction" .Location = "Zoo hospital" .TextBody = "Tiger needs an incisor extracted." ' Save the appointment to a calendar .DataSource.SaveToContainer urlSurgeryFld End With End Sub
由其他物件開啟CDO物件
可以使用DataSource.OpenObject方法由其他記憶體中的物件開啟CDO物件,而記憶體中的物件可以是其他CDO物件或是其他函式庫的物件,如ADO 2.5。
OpenObject方法的語法如下:
Sub OpenObject( Source As Unknown, InterfaceName As String)
參數用法:
Source
被欲開啟物件所參照的已開啟物件,例如一個ADO record或一個已開啟的電子郵件,其通常是一個物件變數。
InterfaceName
Soure所公開的介面名稱字串。例如,假使Source是電子郵件的BodyPart物件,則InterfaceName就是BodyPart,此引數有區分大小寫字母。
DataSource.OpenObject方法可以開啟內嵌郵件(embedded message)作為其單獨的郵件物件或是附件檔案的資料流(streaming)資料。您也可以使用DataSource.OpenObject方法將CDO物件結合至ADO物件。您或許會問為何要這麼做?您可能已經使用Recordset物件來瀏覽Web儲存系統、可能使用Connection物件執行SQL查詢來篩選所需要的項目,又或是批次地建立新項目,但您可能還是需要使用CDO設定物件指定(object-specific)的屬性。
若欲修改使用OpenObject方法開啟CDO物件,需要使用DataSource.SaveToObject方法將變更儲存回parent物件,儲存時傳遞與使用DataSource.OpenObject方法的相同引數給DataSource.SaveToObject方法。
範例程式5-4的程式碼由ADO Record物件開啟一個CDO Folder物件來使用CDO Folder物件屬性。使用此方式開啟資料夾,Record物件變數與 _Record介面名稱被傳遞給Folder物件的DataSource.OpenObject方法,底線符號(_)表示此為介面名稱而不是物件。測試完資料夾描述之後,程式碼使用DataSource.IsDirty屬性判斷物件開啟後是否被修改,若有物件經過更新,則會將變更儲存Record物件。
範例程式5-4:由ADO Record開啟CDO Folder
Sub BindingCDOFoldertoADORecord() ' Open a CDO Folder object from ' an ADO Record object Dim rec As ADODB.Record Dim rst As ADODB.Recordset ' Create a new ADO record object Set rec = New ADODB.Record ' Open the demo folder with ADO rec.Open GetStorageName & "Applications/Zoo Management/" , , adModeReadWrite ' If you are using VBScript, use this With: ' With CreateObject("cdo.folder") With New CDO.Folder ' Link the folder datasource to the data in the open ADO record ' "_Record" is the interface name. ' Note that the interface name is ' case-sensitive. .DataSource.OpenObject rec, "_Record" ' Create a new description if blank If Len(.Description) = 0 Then .Description = "This folder contains zoo information." End If ' If changes have been made... If .DataSource.IsDirty Then ' Save the changes back to the record .DataSource.SaveToObject rec, "_Record" End If ' Print some of the stats of the folder Debug.Print .HasSubFolders Debug.Print .ContentClass Debug.Print .Description End With ' Open a recordset on the objects within the folder ' including any subfolders Set rst = rec.GetChildren Do Until rst.EOF ' Print the HREF for each resource in the folder Debug.Print rst.Fields("DAV:href") rst.MoveNext Loop ' Close the record object and the Recordset object rec.Close rst.Close 'Clean up Set rec = Nothing Set rst = Nothing End Sub
檢查資料夾或項目是否存在
協同作業應用程式的開發人員時常要面對項目重複的問題,CDO並沒有提供比較簡單的方式檢查資料夾或項目是否早已存在。雖然使用儲存方法中的參數可以覆寫資料夾或項目,但是想要在項目不存在時才建立新項目的狀況怎麼辦?例如,您可能需要只有在資料夾不存在時才建立新的資料夾,又或者想要沒有某個連絡人時才建立該連絡人。測試項目是否存在最簡單的方法就是以URL開啟一個ADO Record來做檢查的動作。藉由使用ADO Open的方法,可以在任何屬性被修改之前先檢查URL是否有效。有關ADO Record的Open方法的詳盡資訊,請參閱
第四章〈ActiveX Data Object與Exchange〉 。
範例程式5-5的程式碼檢查URL是否已經存在。當呼叫此函式時,要傳遞欲檢查的URL給此函式,接著程式碼會嘗試以該URL開啟一個Record,如果URL不存在則會失敗。Visual Basic與VBScript中有使用錯誤控制(error handling),因為錯誤捕捉(error trapping)功能關閉,所以當ADO Open方法有錯誤產生時程式碼也會繼續執行。當有錯誤產生時,URL並不會指向Web儲存系統中已存在的資源,且函式傳回值是False。若沒有錯誤產生,URL便指向Web儲存系統中的有效資源,並且函式傳回值是True。您可以使用AlreadyExists函式檢查任何項目是否存在。
範例程式5-5:檢查項目是否存在
Function AlreadyExists(ResourceURL As String) As Boolean ' Checks to see if a resource already exists ' at the URL passed to the function Dim rec As ADODB.Record ' Allow error trapping in both VB and VBScript On Error Resume Next ' Attempt to open an ADO record for the URL Set rec = New ADODB.Record rec.Open _ ResourceURL _ , _ , adModeReadWrite _ , adFailIfNotExists ' Check to see if an error was generated If Err.Number <> 0 Then ' URL does not already exist AlreadyExists = False Else ' URL already exists AlreadyExists = True rec.Close End If ' Turn error handling back to the system ' Change this to go to your current error handler ' if you are using VB On Error GoTo 0 ' Clean up Set rec = Nothing End Function
資料夾的處理
CDO Folder物件表示Web儲存系統中的單一資料夾,您可以使用Folder物件建立新資料夾或開啟既有的資料夾並且設定資料夾指定(folder-specific)的屬性。您也可以使用ADO來修改資料夾,因為資料夾被視為records儲存於Web儲存系統中,ADO可以完成此工作,而CDO無法達到此目的。例如,您可以使用ADO查詢一個特定型態的所有資料夾,如連絡人資料夾,然而欲設定資料夾屬性則應該使用CDO。
本節列出CDO Folder物件的屬性,並說明如何使用CDO建立資料夾、啟動資料夾接收電子郵件,以及計算資料夾中的內容。
CDO Folder物件屬性
CDO提供了一些Folder物件的屬性,讓您可以設定資料夾指定的動作與獲得狀態資訊。表5-3列出CDO Folder物件的屬性。
表5-3 CDO Folder物件的屬性 |
屬性 | 資料型態 | 說明 |
---|---|---|
Configuration | Configuration | 傳回資料夾相關的Configuration物件。 |
ContentClass | String | 設定或傳回資料夾的內容類別。 |
DataSource | IDataSource | 傳回IDataSource介面(唯讀)。 |
Description | String | 設定或傳回資料夾相關的文字敘述。 |
DisplayName | String | 傳回資料夾不含路徑的名稱(唯讀)。 |
EmailAddress | String | 傳回指定給資料夾的電子郵件地址(如果有的話)(唯讀)。 |
Fields | Fields | 傳回資料夾內容類別的fields集合物件(唯讀)。 |
HasSubFolders | Boolean | 資料夾若有子資料夾,則傳回True(唯讀)。 |
ItemCount | Long | 傳回資料夾中所有項目的數量,不包含子資料夾(唯讀)。 |
UnreadItemsCount | Long | 傳回資料夾中所有被標記為未讀取項目的數量(唯讀)。 |
VisibleCount | Long | 傳回所有非隱藏項目的數量(唯讀)。 |
使用CDO建立資料夾
使用CDO建立資料夾時,要建立新的CDO Folder物件,然後設定您希望其運作方式的相關屬性。假使您設定資料夾保存特定型態的項目,便要設定ContentClass屬性為其中一個事先定義的內容類別;若要讓資料夾也可以被MAPI的用戶端所使用,則要設定http://schemas.microsoft.com/exchange/outlookfolderclass屬性。在設定完所有必需的屬性之後,將所有修改儲存至存放區。假使有使用到Fields集合物件來設定屬性,要先呼叫Update方法,再呼叫DataSource.SaveTo方法以建立資料夾。
範例程式5-6說明如何在名為Zoo Management的Web儲存系統應用程式中,建立一個新的資料夾存放有關獸醫的連絡人資訊(Information about vets)。在呼叫AlreadyExists函式檢查相同名稱的資料夾是否存在之後,此程序建立一個新的資料夾物件並設定一些描述資料夾的屬性。此程序也設定ContentClass屬性為資料夾存放連絡人資訊做最佳化的處理。為了使MAPI的用戶端可以使用資料夾的所有功能,也設定了與MAPI相同的屬性。最後資料夾會被建立在Web儲存系統中,任何相同URL的資料夾會被新資訊覆寫。有關內容類別更詳盡的資訊,請參閱
範例程式5-6:建立一個公用資料夾
Sub CreateFolder_CDO() ' Create a new folder in the Zoo Management application Dim urlVetsFld As String ' Build the URL to the new folder urlVetsFld = _ GetStorageName & "Applications/Zoo Management/Vets/" If AlreadyExists(urlVetsFld) Then ' Contact already exists Debug.Print "This folder already exists: " & urlVetsFld Exit Sub End If ' If you are using VBScript, use this With: ' With CreateObject("cdo.folder") With New CDO.Folder ' Set a description about the folder .Description = "Information about vets." ' Configure the folder to hold contact information .ContentClass = "urn:content-classes:contactfolder" ' Make the contact folder usable by Outlook .Fields("http://schemas.microsoft.com/exchange/outlookfolderclass") = _ "IPF.contact" ' Save the changes .Fields.Update ' Create the new folder by saving it to the public store .DataSource.SaveTo urlVetsFld End With End Sub
提示
欲從資料夾階層架構中刪除一個資料夾,可以使用ADO存取資料夾record,然後再呼叫DeleteRecordz方法。有關更多的詳細資訊請參閱第四章〈ActiveX Data Objects與Exchange〉 。
啟動資料夾接收電子郵件
當資料夾被建立時,預設並無法藉由SMTP接收郵件,必須要明確地啟動資料夾來接收電子郵件。CDO IMailRecipient介面的MailEnable方法可以達成此目的,Exchange會自動指定一個電子郵件地址給資料夾。
要啟動資料夾來接收電子郵件,資料夾必須已經存在於資料夾樹狀結構中。假使要在建立新資料夾的同時也啟動資料夾接收電子郵件,要先儲存資料夾,然後再呼叫MailEnable方法。若只是啟動既有的資料夾來接收電子郵件,於呼叫MailEnable方法之前資料夾不需要再儲存一次。
範例程式5-7展示如何建立並啟動資料夾來接收電子郵件。此程序先呼叫AlreadyExists檢查資料夾是否已經存在,如果資料夾已存在,則開啟為編輯模式,如果資料夾不存在,則建立新的資料夾並將之儲存至資料夾樹狀結構中。要啟動資料夾接收電子郵件,此程序必須存取IMailRecipient介面,因為程式碼是以Visual Basic撰寫,而且IMailRecipient介面物件變數宣告為CDOEXM. IMailRecipient,所以程式碼可以將IMailRecipient介面物件變數指到Folder物件變數,並且資料夾會自動傳回適當的介面,當介面被參照時,此程序會呼叫MailEnable方法。為確定資料夾的電子郵件地址會顯示在Microsoft Outlook通訊錄之中,此程序也設定HideFromAddressBook屬性為False。
範例程式5-7:建立一個可以藉由SMTP接收電子郵件的資料夾
Sub MailEnableFolder() ' Create a folder that can receive email Dim urlNotices As String Dim fldr As CDO.Folder Dim rcp As CDOEXM.IMailRecipient Set fldr = New CDO.Folder 'Build the URL to the new folder urlNotices = GetStorageName & _ "applications/zoo management/facilities/" If AlreadyExists(urlNotices) Then ' Open the folder fldr.DataSource.Open urlNotices, , adModeReadWrite Else ' Create a new folder fldr.DataSource.SaveTo urlNotices, , adModeReadWrite End If ' Reference the IMailRecipient interface ' If you are using VBScript, access the interface like this 'Set rcp = fldr.GetInterface("IMailRecipient") Set rcp = fldr ' Mail enable the folder and generate the email addresses With rcp .HideFromAddressBook = False End With ' Save the folder again fldr.DataSource.Save 'Clean up Set fldr = Nothing Set rcp = Nothing End Sub
說明
有關更多設定電子郵件收件者的相關資訊,請參閱第八章〈與Active Directory互動〉 。
計算資料夾中的內容
另一個使用CDO Folder物件的理由,就是用來計算資料夾中內容的數量。使用ADO計算資料夾中的資源時,必須瀏覽此資料夾,並將資料夾的內容填入Recordset物件中,然後再呼叫RecordCount屬性。這種方式不止忽視內容到底是項目還是其他資料夾,而且還要視Recordset物件使用哪一種型態的游標(cursor),可能會時常得到資料夾中項目的數量與實際數量不符的結果。另一個使用ADO的作法是使用Recordset物件以及使用一個變數來計算迴圈執行的次數。因為此種方式需要接觸到Recordset物件中的每一個資源,所以當Recordset物件中的資源相當龐大時,會產生伺服器原本不需要的負載。
使用CDO可以避免程式碼中有不明確的狀況發生,以及造成伺服器的負載過重,Folder物件提供三種計算資料夾內容的屬性:
- ItemCount屬性計算資料夾中所有不包含子資料夾的項目數量。
- Unread ItemCount屬性只計算未被標記為已讀取的項目數量。
- VisableCount屬性只計算那些使用者可見並可存取的項目,忽略可能儲存於資料夾中的系統隱藏項目。
範例程式5-8的程式碼讀取CDO Folder物件的一些屬性。在資料夾開啟之後,程式碼傳回資料夾的內容類別以及多種項目的數量。
範例程式5-8:取得資料夾的項目數量相關資料
Sub CountFolderContents() ' Return the various item counts on a folder Dim urlKeepersFld As String ' Build the URL to the folder urlKeepersFld = GetStorageName & _ "Applications/Zoo Management/Staff/" ' If you are using VBScript, use this With: ' With CreateObject("cdo.folder") With New CDO.Folder ' Open the folder .DataSource.Open urlKeepersFld ' Return some information including the counts Debug.Print _ "DisplayName = " & .DisplayName Debug.Print _ "ContentClass = " & .ContentClass Debug.Print _ "EmailAddress = " & .EmailAddress Debug.Print _ "Description = " & .Description Debug.Print _ "ItemCount = " & .ItemCount Debug.Print _ "UnreadItemCount = " & .UnreadItemCount Debug.Print _ "VisibleCount = " & .VisibleCount End With End Sub
連絡人資訊的處理
連絡人是什麼?這並不是一個可以三言兩語就道盡的專有名詞。由於商業行為日趨繁複,因此使用一些物件來表示這些行為,尤其是用來定義一個「人」的相關資訊的物件。在Exchange裡,連絡人可以是Web儲存系統中的資源,也可以是Active Directory中的資源;在資料夾裡,連絡人是有關個人的相關資訊;在Active Directory裡,連絡人是儲存有關人員的基本資訊的項目,也是登入網路的使用者物件。不管是哪一類的資源,都可以使用CDO Person物件建立新的連絡人,或是編輯既有的連絡人的相關資訊。
使用哪種方式將Person物件結合至目標資源取決於連絡人位於何處。當您在Web儲存系統資料夾中處理連絡人資訊時,要使用以ExOLEDB provider建立的典型URL。欲結合Person物件至Active Directory中的資訊,需要使用LDAP(Lightweight Directory Access Protocol)provider建立一個不同的URL。在將Person物件結合至適當資源之後,您便可以使用urn:schemas:contacts名稱空間中的任何屬性變數來儲存有關人員的各種資訊,例如:姓名、電話號碼、電子郵件地址與實際地址。使用連絡人資料,您可以打電話給他們、傳送電子郵件給他們,以及安排在他們的辦公室進行會議。本節列出Contact相關屬性,並且說明如何在Web儲存系統中建立連絡人,以及擷取vCard中的相關資訊。
說明
本章並不討論使用Person物件與Active Directory中物件的關係。然而在大多數的狀況中,CDO Person物件相同的核心功能,也可以應用在Active Directory中的連絡人與使用者物件。您也不能使用Person物件建立與管理通訊群組清單(distribution lists),亦即現在所謂的群組,群組必須由Active Directory來維護,並且要使用ADSI(Active Directory Service Interfaces)來存取。有關使用CDO Person物件管理Active Directory中的使用者物件以及ADSI與群組更多的資訊,請參關
Contact屬性
詳細描述人員以及人員行為需要相當多的資訊,從個人嗜好、性別到跟電腦比較相關的資訊,如proxy位址等,於Web儲存系統與Active Directory建立新的連絡人時,均必須將個人的相關資訊儲存於連絡人之中。為了容納所有的資訊,結構描述定義了範圍廣泛的許多屬性。事實上,urn:schemas:contacts: 名稱空間是Exchange裡其中一個定義最多的結構描述屬性,其定義了超過140個的屬性。因為只有少數比例的屬性被實際作為CDO介面屬性,所以您必須知道在使用Person物件的Fields集合物件存取時,結構描述屬性或是常數的名稱。
表5-4至表5-14以功能為主,列出了連絡人屬性,如此一來,以名稱來尋找時,應該會方便一些。除了資料型態與描述之外,每個表格還包含下列資訊:
- urn:schemas:contacts: 屬性名稱:在Web儲存系統結構描述中用來辨識的屬性名稱,結構描述屬性名稱有區分字母大小寫,所以必須使用與表格欄位中完全相同的屬性名稱。有些屬性名稱的長度比較長,所以名稱會被截成多行,這種狀況發生時,並非表示要在名稱中間加上空白字元。
- CDO常數:此欄位中若有值的話,即表示其為CDO常數,您可以在完整的結構描述屬性名稱中使用此常數。與結構描述屬性名稱相同,有些常數名稱太長也會被截成多行,這種狀況發生時,並非表示要在名稱中間加上空白字元。
- CDO屬性:此欄位中含有CDO Person物件的屬性,如果此欄位有值的話,是為了結構描述屬性而存在。CDO物件屬性是最容易使用的。
表5-4 Name屬性 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
givenName | cdoFirstName | FirstName | String | 名字 |
middlename | cdoMiddle Name | Middle Name | String | 中間名稱(英文名稱才有) |
sn | cdoSurname | LastName | String | 姓氏 |
namesuffix | cdoNamesuffix | Name Suffix | String | 附加名字(如Sr.、Jr. II或III) |
personaltitle | cdoPersonalTitle | Name Prefix | String | 稱呼(如Miss、Ms. Mrs.、M. 或Mr.) |
initials | cdoInitials | Initials | String | 縮寫(如英文名稱的姓與名所有第一個字母結合而成) |
cn | cdoCommon | Name | N/A | Sring 一般名稱(替代人員 的完整名稱) |
nickname | cdoNickName | N/A | String | 暱稱(易記名稱) |
fileas | CdoFileAs | FileAs | String | 指定檢視連絡人名稱時如何排序 |
表5-5 Identification屬性 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
customerid | cdoCustomerID | N/A | String | 使用者定義 |
fileasid | cdoFileAsID | N/A | Long | 使用者定義 |
governmentid | cdoGovernment Id | N/A | String | 使用者定義 |
internationalisdn number | cdoInternational ISDNNumber | N/A | String | 使用者定義 |
employeenumber cdoEmployee | Number | N/A | String | 使用者定義 |
表5-6 E-mail address與URL欄位 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
email1 | cdoEmail1 Address | String | 連絡人主要的電子郵件地址 | |
email2 | cdoEmail2 Address | Email2 | tring | 連絡人次要的電子郵件地址 |
email3 | cdoEmail3 Address | Email3 | String | 連絡人第三個電子郵件地址 |
proxyaddresses | cdoProxy Addresses | Email Addresses | Variant | 包含一個或一個以上用戶端電子郵件地址的字串 |
sourceurl | cdoSourceURL | N/A | String | 伺服器中連絡人資料來源的URL |
personalHome Page | cdoPersonalURL | N/A | tring | 連絡人個人網頁的URL |
businesshome page | N/A | N/A | String | 連絡人公司的網頁的URL |
ftpsite | cdoFTPSite | N/A | String | 連絡人的FTP站台的URL |
mapurl | cdoMapURL | N/ A | String | 連絡人地圖的URL(唯讀) |
表5-7 其他的電腦相關屬性 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
authorig | cdoOriginal Author | N/A | String | 建立連絡人的人員名稱 |
submission contlength | cdoSubmission ContentLength | N/A | Long | 可傳送給連絡人最大郵件的限制 |
usercertificate | cdoUser Certificate | N/A | Byte | 用來認證連絡人的數位簽章 |
protocolsettings | cdoProtocol Settings | N/A | String | 指定Internet通訊的二進位字串 |
dn | cdo Distinguished Name | N/A | String | 辨識連絡人名稱,包含網域名稱(唯讀) |
contact | N/A | N/A | String | Microsoft Hotmail用來擷取連絡人資訊的XML元素(唯讀) |
computer network name | cdoComputer Network Name | N/A | String | 電腦網路名稱 |
表5-8 Telephone number屬性 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
othertimezone | cdoOtherTime Zone | N/A | String | 工作地點的時區 |
telephoneNumber | cdoWorkPhone | Work Phone | String | 工作地點的電話號碼 |
telephonenumber2 | cdoWorkPhone2 | N/A | String | 工作地點的另一個電話號碼 |
otherTelephone | cdoOther Telephone | N/A | String | 工作地點的其他電話號碼 |
facsimile telephonenumber | cdoWorkFax | WorkFax | String | 工作地點的傳真號碼 |
otherfax | doOtherFax | N/A | String | 工作地點的另一個傳真號碼 |
telexnumber | cdoTelexNumber | N/A | String | 電報號碼(工作地點) |
pager | cdoPager | Work Pager | String | 工作用的呼叫器號碼 |
otherpager | cdoOtherPager | N/A | String | 工作用的另一個呼叫器號碼 |
mobile | cdoMobile | Mobile Phone | String | 行動電話號碼 |
othermobile | cdoOtherMobile | N/A | String | 另一個行動電話號碼 |
callbackphone | cdoCallBack Phone | N/A | String | 回撥的電話號碼 |
hometimezone | cdoHomeTime Zone | N/A | tring | 住家的時區 |
homePhone | cdoHomePhone | Home Phone | String | 住家的電話號碼 |
homephone2 | cdoHome Phone2 | N/A | String | 住家的另一個電話號碼 |
homefax | cdoHomeFax | HomeFax | String | 住家的傳真號碼 |
otherfacsimile telephonenumber | cdoOtherFax Number | N/A | String | 住家的另一個傳真號碼 |
表5-9 Physical address屬性—work |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
o | cdoOrganization Name | N/A | String | 公司或組織的名稱 |
department | cdoDepartment | N/A | String | 部門名稱 |
roomnumber | cdoRoom Number | N/A | String | 辦公室編號 |
location | N/A | N/A | String | 位置或地區 |
workaddress | cdoWorkAddress | Work Postal Address | String | 工作地點郵遞區域、縣/市、鄉/鎮/市/區、街名的組合欄位(唯讀) |
street | cdoWorkStreet | Work Street | String | 工作地點的地址 |
postofficebox | cdoPostOffice Box | N/A | String | 工作地點辦公室的郵政信箱 |
l | cdoWorkCity | WorkCity | String | 工作地點的所在城市 |
st | cdoWorkState | WorkState | String | 工作地點州名的縮寫 |
postalcode | cdoWorkPostal Code | Work Postal Code | String | 工作地點的郵遞區號 |
c | Abbreviation | N/A | String | 工作地點所在國家的名稱縮寫 |
co | cdoWorkCountry | Work Country | String | 工作地點所在國家的一般名稱,若有使用便要搭配國家名稱的縮寫 |
表5-10 Physical address屬性—home |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
homepostal address | cdoHomePostal Address | Home Postal Address | String | 住家郵遞區域、縣/市、鄉/鎮/市/區、街名的組合欄位(唯讀) |
homeStreet | cdoHomeStreet | Home Street | String | 住家街道地址 |
homepostoffice box | cdoHomePost OfficeBox | Home- PostOffice Box | String | 住家郵政信箱 |
homeCity | cdoHomeCity | HomeCity | String | 住家所在的城市 |
homeState | cdoHomeState | HomeState | String | 住家州名的縮寫 |
homePostalCode | cdoHomePostal Code | Home Postal Code | String | 住家郵遞區號 |
homeCountry | cdoHome Country | Home Country | String | 住家所在國家的名稱縮寫 |
homelatitude | cdoHome Latitude | N/A | Double | 住家緯度 |
homelongitude | cdoHome Longitud | N/A | Double | 住家經度 |
表5-11 Physical address屬性—package與mail傳送 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
mailingaddressid | cdoMailing AddressID | Mailing Address ID | Cdo Mailing Address Id Values | 遞送包裹的地址,不管是工作地點、住家、或其他地址欄位,亦或是新的地址。 |
mailingpostal Address | cdoMailing Postal Address | Mailing address | String | 遞送包裹的街名、城市、州名、郵遞區域(唯讀) |
mailingstreet | cdoMailingStreet | N/A | String | 遞送包裹的街道地址(唯讀) |
mailingp bo ostoffice | cdoMailingPostx OfficeBox | N/A | String | 遞送包裹的郵政信箱(唯讀) |
mailingcity | cdoMailingCity | N/A | String | 遞送包裹的城市(唯讀) |
mailingstate | cdoMailingState | N/A | String | 遞送包裹州名的縮寫(唯讀) |
mailingcountry | cdoMailing Country | N/A | String | 遞送包裹國家名稱的縮寫(唯讀) |
表5-12 Physical address屬性—second home或alternative address |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
otherpostaladdress Address | cdoOtherPostal | N/A | String | 另一個遞送包裹的街名、城市、州名、郵遞區域的組合欄位(唯讀) |
otherstreet | cdoOtherStreet | N/A | String | 另一個街道地址 |
otherpostofficebox | cdoOtherPost OfficeBox | N/A | String | 另一個郵政信箱 |
othercity | cdoOtherCity | N/A | String | 另一個城市 |
otherstate | cdoOtherState | N/A | String | 另一個州名的縮寫 |
otherpostalcode | cdoOtherPostal Code | N/A | String | 另一個郵遞區域 |
othercountrycode | cdoOther CountryCode | N/A | String | 另一個國家名稱的縮寫 |
othercountrycdo- Other | Country | N/A | String | 另一個國家的一般名稱 |
表5-13 Associated people屬性 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
manager | cdoManager | N/A | String | 連絡人的經理之全名 |
managercn CommonName | cdoManager | N/A | String | 連絡人的經理之易記名稱 |
secretary | cdoSecretary | N/A | String | 連絡人的秘書之全名 |
secretarycn CommonName | cdoSecretary | N/A | String | 連絡人的秘書之易記名稱 |
secretaryurl | cdoSecretaryURL | N/A | String | 連絡人的秘書之URL |
spousecn CommonName | cdoSpouse | N/A | String | 連絡人的配偶之易記名稱 |
childrensnames | cdoChildren Names | N/A | Variant | 連絡人的子女之清單(多重值) |
表5-14 其他欄位 |
urn:schemas: contacts: 屬性 | CDO常數 | CDO屬性 | 資料型態 | 說明 |
---|---|---|---|---|
account | cdoAccount | N/A | String | 使用者定義 |
title | cdoTitle | Title | String | 連絡人工作上的職稱 |
profession | cdoProfession | N/A | String | 連絡人的專業地位或角色 |
language | cdoLanguage | N/A | String | 連絡人於IS639格式中所說的語言 |
gender | cdoGender | N/A | Integer | 連絡人的性別(男、女或 未知) |
bday | cdoBirthday | N/A | Date | 連絡人的生日日期 |
hobbies | cdoHobbies | N/A | ring | 連絡人的個人嗜好清單 |
billinginformation | N/A | N/A | String | 帳單資訊的字串,如鐘點費的費率 |
Wedding anniversary | cdoWedding anniversary | N/A | String | 連絡人的結婚紀念日 |
在Web儲存系統中建立連絡人
欲使用CDO在Web儲存系統中建立連絡人,要先建立一個新的Person物件,再設定一些描述連絡人的相關屬性,然後再呼叫DataSource.SaveTo方法儲存連絡人,也有另外一個方法可供選擇,就是DataSource.SaveToContainer方法。然而,誠如本章先前所提到,DataSource.SaveToContainer方法無法明確地指定URL的DAV:displayname屬性之後的確切內容,而DataSource.SaveTo方法可以達到此目的。相反地,Exchange會自動設定給DAV:displayname屬性一個GUID(globally unique identifier),看起來就像: E180EECE-36A5-498E-BB80-C8A5FE6C33C8。
如此會造成一些問題。首先,雖然GUID對Web儲存系統而言是有意義的,但是對使用者而言並沒有意義。所以如果您打算顯示DAV:displayname屬性值或甚至是項目的URL,GUID可能會產生令人困惑的情形。再者,因為GUID是由Exchange自動產生,所以GUID永遠是唯一的。也就是說,假使您沒有注意而將相同的連絡人資訊輸入許多次,也不會有任何錯誤狀況發生。為避免同一個連絡人有多個項目的情形,在建立連絡人時使用DataSource.SaveTo方法,而且在建立前先要檢查是否已經有相同身份的連絡人存在。
擷取vCard資訊
並非所有電子郵件的用戶端應用程式都可以解譯MAPI格式的郵件,為了與其他資訊管理程式有最好的相容性,連絡人的資訊可以被公開為稱作vCards的MIME格式檔案。使用GetVCardStream方法可以存取或建立連絡人的vCard相關資訊,此方法傳回可供修改的ADO Stream物件。例如,您可以將vCard資訊儲存為本機硬碟中的檔案,將這些資訊嵌入電子郵件中,或附加至其他項目當中。
範例程式5-9的程式碼便是使用GetVCardStream方法展開Web儲存系統資料夾中的vCard資訊,程式碼將vCard資訊寫入本機磁碟的一個檔案中。開啟連絡人之後,呼叫GetVCardStream方法並以ADO Stream物件的形式傳回連絡人資訊。因為子程序只將結果寫至本機磁碟中,所以隨即呼叫SaveToFile方法,並且傳遞新的檔案名稱,以及指定覆寫相同URL的既有檔案。藉由在呼叫GetVCardStream方法的陳述式中使用SaveToFile方法,便不需要建立Stream物件。然而您還是需要在專案中參照ADO 2.5物件,假使您想要進一步修改Stream物件中的內容,應該分別建立Stream物件變數,然後將物件變數指向GetVCardStream的結果,再來修改當中的資訊。
範例程式5-9:以vCard傳回連絡人資訊
Sub GetVCardInformation() ' Return a contact as a vCard file Dim urlStaffMember As String urlStaffMember = GetStorageName & _ "Applications/Zoo Management/Staff/Amy Luehmann.EML" If Not AlreadyExists(urlStaffMember) Then ' This URL does not exist Debug.Print "Contact does not exist at that URL." Exit Sub End If ' If you are using VBScript, use this With: ' With CreateObject("cdo.person") With New CDO.Person 'Open the existing contact .DataSource.Open urlStaffMember 'Save the vCard information to a local file .GetVCardStream.SaveToFile "C:\vCard", adSaveCreateOverWrite End With End Sub
執行範例程式5-9時會產生一個檔案,若以Microsoft記事本來開啟,則結果看起來就像圖5-1的檔案。
圖5-1執行範例程式5-9時,會產生一個連絡人的vCard資訊檔案。 |
本章總結
CDO for Exchange提供物件、類別與介面,來建構功能強大的協同作業解決方案。瀏覽Web儲存系統,ADO 2.5有最佳的表現;以協同作業為目的修改獨立資源時,CDO可以有最佳的表現。您可以使用CDO來傳送電子郵件、安排約會、管理連絡人,以及維護資料夾。當您使用CDO處理連絡人資訊時,藉由眾多公開的連絡人結構描述屬性,提供您選擇用來方便地存取連絡人資訊,CDO甚至提供簡單的方法以存取vCard資訊。假使您的目的是建立與管理資料夾,CDO提供資料夾設定的屬性,以及存取用來做資料夾管理的物件。