随笔 - 58,  文章 - 55,  评论 - 146,  阅读 - 12万

 

開發人員在先前版本的微軟 Exchange 資料存取功能上可能會面臨到一些限制,在 Exchange 5.5 中雖然可以儲存幾乎所有型態的資料,但當您要用程式來對資料作存取時就會有一些限制。隨著 Exchange 2000 的問世,這種狀況將不復存在。Exchange 仍然是儲存大量資料的最佳選擇,而且同時還包含了更強大且更有效率的資料存取功能。藉著使用微軟 Active Data Object(ADO)2.5 與 Exchange OLE DB(ExOLEDB)provider,您可以與儲存在微軟 Web 儲存系統內的資料作互動,如同存取微軟 Access 或微軟 SQL 伺服器中的資料一樣地簡便容易,您可以建立、編輯和刪除資源,同時也可以複製與移動資源及使用結構化查詢語言(Structured Query Language, SQL)來執行查詢動作,甚至可以直接將資料夾中的內容轉換為 Extensible Markup Language(XML)文件。

本章將說明如何使用 ADO 來存取及瀏覽 Web 儲存系統,章節內容如下:

  • ActiveX Data Objects 2.5 與 Exchange簡介
     
  • 連線至 Web 儲存系統
     
  • 使用 Record 物件
     
  • 使用 Recordset 物件
     
  • 使用 SQL SELECT 陳述式來查詢 Web 儲存系統
     
  • ADO 的更多功能
     
  • 結合 ADO 與 Microsoft Internet Publishing Provider
     

ActiveX Data Objects 2.5 與 Exchange簡介
 

ActiveX Data Objects 2.5 是針對 OLE DB 設計的一個 script 介面,用來存取任何擁有 OLE DB provider 的資料儲存系統。在安裝 Microsoft Windoows 2000 時,也會自動安裝 ADO 至系統中,並且支援所有支援 Component Object Model(COM)物件的程式語言,包含 Visual Basic、Microsoft Visual Basic Scripting Edition(VBScript)以及 Microsoft Visual C++。這使得 ADO 成為最佳的資料存取介面,在此之前,ADO 已經用來存取 Access 與 SQL 伺服器之類的資料儲存系統有一段時間了,現在 ADO 2.5 也可以透過 ExOLEDB provider 來存取 Web 儲存系統。

本節將介紹 ADO 2.5 物件模型及 ExOLEDB provider,接著說明 Record 與 Recordset 之間的關係以及 ADO 的安全性是如何運作的。

ADO 2.5 物件模型
 

ADO 2.5 物件模型有著簡潔的設計,整個模型中只包含幾個少數的物件。圖 4-1 說明 ADO 2.5 物件模型,在物件模型中的物件與群組(collection)包含了:

  •  Connection: Connection 物件代表著與伺服器間的連線狀態,您可以明確地指定一個 provider 及連線字串後再開啟連線,或是直接藉由開啟一個 record 或 recordset 來開啟連線。
     
  •  Command: Command 物件針對資料來源定義了特定的執行指令,通常是使用 SQL 指令,Command 物件也可以配合 Parameter 集合物件來執行參數查詢。
     
  •  Recordset: Recordset 物件是資料的集合,由許多筆資料記錄(record)所組成。Recordset 可以是資料夾中的項目集合或是資料夾集合,一個 Recordset 並不一定需要包含多筆記錄,可以只包含單一項目或資料夾。
     
  •  Record: Record 物件代表了單一的資源,例如在收件匣中的一封電子郵件、在 Web 儲存系統資料夾中的一篇公告,甚至是一個單一的資料夾。
     
  •  Error: Errors 集合物件包含了一些獨立的物件,用來回應當連線資料來源時 provider 所產生的錯誤。
     
  •  Stream: Stream 物件代表了二進位資料或文字的資料流。藉由使用 Stream 物件,在以 bit 為單位的資料流中,您可以建立、管理及讀取項目與檔案,而不需要存取一大塊的記憶體。
     
  •  Parameters: Parameter 集合物件包含了許多用來傳遞給 Command 物件以執行參數查詢的單獨引數或條件。
     
  •  Fields: Fields 集合物件是用來為資源建立結構描述的屬性。例如,一個 Record 物件便需要一個 Fields 集合物件來保有所有用來定義資源的結構描述屬性。
     


 

 圖 4-1 ADO 2.5 的物件模型

Exchange OLE DB Provider
 

當您撰寫用來存取 Web 儲存系統資料的程式碼時,便會使用到 Exchange OLE DB(ExOLEDB)provider 來存取資料。ExOLEDB 是一個利用 ADO 2.5 Collaboration Data Objects(CDO)for Exchange來存取 Web 儲存系統資源最新且最有效率的OLE DB provider,ExOLEDB 隨著 Exchange 2000 安裝至系統,是只能使用於伺服器端的元件,這也表示您必須在伺服器端執行 ExOLEDB。圖 4-2 說明了 ADO、ExOLEDB provider 與 Exchange 間的關係。

如果您必須在伺服器端執行 ExOLEDB,該如何建立您的程式?雖然您的程式必須在放在伺服器端,但這對您想建立的程式並不會有任何限制。您可以建立採用 ASP 技術的 Web 應用程式,同時可以將程式功能建立於 COM 元件之中,例如使用 Visual Basic 或 Visual C++ 建立的 ActiveX DLLs 及可執行的檔案(.exe 檔),當您要建立 event sinks 及 workflow event sinks 時,也可以使用 ExOLEDB。


 

 圖 4-2 ADO 2.5 與 ExOLEDB 間的關係

說明

ADO 藉由 ADO 物件提供了許多屬性及方法,然而這也要取決於 OLE DB provider 支援了哪些屬性與方法。雖然 ExOLEDB 支援了大部分的屬性與方法,但它並不支援某些特性,包含在許多 ADO 方法中適用的 UserName 及 Password 參數、游標型態(cursor type)的選擇、record 鎖定的選項及巢狀的交易(nested transactions)。


了解 Record 與 Recordset 間的關係
 

您可以使用 ADO Record 與 Recordset 物件來瀏覽 Web 儲存系統並存取儲存在其中的資料。您可以使用 Record 物件來開啟如郵件或連絡人資訊之類的項目,並使用 Recordset 來傳回資料夾或項目的集合物件。有時 Record 與 Recordset 物件會同時用來完成存取資料夾中資料的任務。本節將藉由範例來說明如何使用 ADO 來瀏覽收件匣中的內容。

圖 4-3 說明了 Exchange 物件與 ADO 物件在一個假設的信箱中的關係。在圖中,最上方的物件代表著一個信箱,要使用 ADO 物件來存取這個信箱,需要開啟一個 ADO Record 物件並將信箱的 URL 傳給此物件,物件開啟之後便可以得到有關信箱的資訊。如果您要傳回內容,便需要使用 Recordset 物件,藉由呼叫代表信箱之 ADO Record 物件的 GetChildren 方法,您可以將資料夾中的內容放至 Recordset 物件中。在本例中,呼叫信箱的 GetChildren 方法將傳回一個 Recordset 物件,其中包含信箱所建立的一些標準的資料夾,例如收件匣、連絡人資訊、行事曆和已傳送項目。您可以經由集合物件來列舉與讀取每一資料夾中的資訊。

欲瀏覽其他的子資料夾,例如收件匣,還是可以使用 ADO Record 與 Recordset 物件來達成目的。在收件匣中開啟 Record 物件後,呼叫 GetChildren 方法將收件匣的內容藉由 Recordset 物件回傳。Recordset 物件不只有收件匣中的訊息,同時也包含了子資料夾。Recordset 物件可包含許多種項目的型態,例如資料夾、項目、Web 檔案及 Office 文件。


 

 圖 4-3 ADO Record 與 Recordset 物件代表了 Web 儲存系統中的每一種資料

了解 ADO 中的安全性
 

當 ADO 2.5 配合 ExOLEDB provider 使用時,所有的程式皆在 ExOLEDB 提供的安全內容(security context)執行,無論任何一個程式使用者都一樣。這代表著一個助理與一個經理在 Web 儲存系統中的存取與操作資源的權限有可能是相同的。從安全性的角度來看,這並不是一個最佳的狀況。

由於 ExOLEDB 並不支援 IAuthentication 介面,因此使用者無法在您的程式中扮演另一個使用者,而導致不同的安全內容之狀況發生。您可以使用 Visual Basic 及 VBScript 來將您的 ADO 2.5 程式放進一個 COM 應用程式中,以定義一個安全環境,接著您可以應用 COM+ 提供的安全性特性來規範一群使用者只能在特定的安全環境下執行程式。有關 COM+ 更多的資訊,請參閱 第十四章〈安全性與權限的設定〉 。

連線至 Web 儲存系統
 

要與 Web 儲存系統內的資料互動,首先必須使用 ADO Connection 物件來建立一個連線,一個單一的 ADO Connection 物件相當於對 ExOLEDB 的單一連線,在連線建立之後,便可以存取 Web 儲存系統內的資料。

您可以經由建立 Connection 物件明確地建立連線,或以 root 不明確地建立連線。當安裝 Exchange 時,會在本機伺服器中註冊 ExOLEDB 為 OLE DB 2.5 的 root binder,作為 File URL 的名稱空間。root binder 是 Window 2000 作業系統的一部份,負責結合 URL 上的資源與 ADO 物件。root binder 省去了當使用 OLE DB/ADO 來存取資源時必須明確建立 Connection 物件的動作。然而這兩種方式都需要有建構完善的 URL 來達成取得或建立一個新資源。本節將介紹如何針對 ExOLEDB 建立 URL 及如何使用 Connection 物件。

為 ExOLEDB 建立 URL
 

URL 定義了資源在 Web 儲存系統中的位置,在 Exchange 中幾乎所有可存取的資源都有 URL,且幾乎所有資料存取的動作也都需要依靠 URL。您需要 URL 來建立新資源和開啟既有的資源,也需要 URL 來複製、移動及刪除資源。

第二章〈Exchange 與 Web 儲存系統〉中說明了如何使用 HTTP/WebDAV 協定建立 URL 來存取在 Web 儲存系統中的資源,並且當 ExOLEDB 隨著 Exchange 2000 安裝時,Exchange 會為 File://URL 名稱空間註冊 ExOLEDB provider,此註冊代表除了可以使用您所建立的 URL 藉由 ExOLEDB 來存取 Web 儲存系統之外,也可以使用 FIle:// 這個名稱空間來存取 Web 儲存系統。一個 ExOLEDB URL 語法如下:

File://./backofficestorage/<Domain DNS name>/<path to a resource>

除了 File://URL 這個名稱空間外,Exchange 也註冊了 backofficestorage 名稱空間。ExOLEDB URL 的第一個部分 File://URL 在任何程式執行的伺服器上都是一樣的,此部份指出 Exchange 的存放區。<Domain DNS name>指出了程式在哪一個網域執行,不像 HTTP/WebDAV 協定是使用 Exchange 伺服器的名稱,File URL 協定是使用網域名稱。下列 URL 說明了如何使用 ExOLEDB 在 domain.com 中存取 Web 儲存系統。

file://./backofficestorage/domain.com

<path to a resource> 部分指出資源位於存放區的位置,資源的完整 URL 儲存於每個資源的 DAV:href 結構描述屬性中。

在本節以及本書所出現幾乎所有的 URL 都是絕對的(absolute)URL,一個絕對的 URL 包含了在 Web 儲存系統中定位資源所有必須的相關資訊;您也可以在 ExOLEDB 中使用相對的(relative)URL,一個相對的 URL 只包含部分位址,並且使用一個絕對的 URL 作為瀏覽階層架構時的參考點。


說明

您可以在 ExOLEDB 中使用 HTTP,然而使用 HTTP 的程式預設上都是使用 Microsoft Internet Publishing Provider。如果要在 ExOLEDB 中使用 HTTP,請明確設定 provider 為 ExOLEDB。


存取公用 Web 儲存系統資料夾
 

要存取一個公用 Web 儲存系統資料夾,請將 Web 儲存系統資料夾樹狀結構的名稱附加在 URL 之後,並且要提供資料夾的路徑,將資料夾的每一階層用正斜線(/)隔開。資料夾的名稱是不分大小寫的,因此無論用哪種大小寫的組合,都不會影響連線的結果。

要存取一個位於 MAPI 公用資料夾樹狀結構中的資料夾,請使用資料夾樹狀結構的名稱 Public Folders 並且附上資料夾的路徑,例如,您可以使用下列 URL 來存取 Internet Newsgroups 位於 domain.com 中的 MAPI 資料夾樹狀結構:

File://./backofficestorage/doamin.com/public folders/Internet Newsgroups/

要存取一個非 MAPI 資料夾樹狀結構,只要將 public folders 換成 Web 儲存系統資料夾樹狀結構的名稱。例如,您可以使用下列 URL 來存取 Zoo Management 應用程式資料夾,其位於 domain.com 中的 Applications 資料夾樹狀結構:

File://./backofficestorage/domain.com/applications/zoo management/

位於最後的斜線對於存取資料夾並不是必需的,然而使用於程式中是為了要幫助您分辨此 URL 是指向一個資料夾或是一個項目。

存取信箱
 

要存取特定使用者的信箱,您必須在 URL 中加上 /MBX/使用者別名/。MBX 是一個用來說明您要存取信箱的常數,而使用者別名則是使用者在 Exchange 中的別名。例如,下列 URL 指向使用者 Mindy 的信箱:

file://./backofficestorage/domain.com/mbx/mindy/

要存取信箱中的標準資料夾,您可以使用下列的URL,並置換為您的Domain Name System(DNS)網域名稱及用於電子郵件的別名:

  • file://./backofficestorage/domain.com/mbx/mindy/Tasks/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Notes/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Journal/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Drafts/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Contacts/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Calendar/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Sent Items/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Deleted Items/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Outbox/
     
  • file://./backofficestorage/domain.com/mbx/mindy/Inbox/
     

ExOLEDB URL 是針對整個網域,而不是只為了個別的 Exchange 資料庫,這表示您不必擔心資料實際儲存的位置,最重要的是當您為私有信箱的存放區建立 URL 時。無論信箱的實際位置在何處,甚至於將信箱搬到另一伺服器中,建立 URL 的方式永遠都是一樣的。

存取項目
 

您可以直接建立一個指向資料夾中項目的 URL,而不用先存取資料夾。要建立一個指向資料夾中項目的 URL,請附加適當的存放區資訊(資料夾樹狀結構或信箱)、資料夾路徑和 DAV:displayname 結構描述屬性值在 URL 之後。下列的 URL 是以「Hello.eml」的 DAV:displayname 值存取收件匣中第一個項目:

file://./backofficestorage/domain.com/mbx/mindy/inbox/hello.eml

說明

如果在一個資料夾中有一個以上有著相同主題的項目,任何一個額外的項目都必須藉由附加號碼在主題後,來指定您想回傳的項目。想知道更多的相關資訊,請參閱 第二章〈Exchange 與 Web 儲存系統〉 。


要存取 Muitipurpose Internet Mail Extensions(MINE)郵件之外的項目,例如微軟 Word 文件或微軟 Excel 試算表,您需要使用標準的附檔名(.doc 與 .xls)。下列 URL 用來存取儲存於公用資料夾中的 Word 文件:

file://./backofficestorage/domain.com/public folders/mindy/cdo final.doc

您也可以使用一個 ADO Stream 物件以位元組形式獲得結構化的文件資訊,在本章稍後 〈Streaming 內容〉 一節中將會說明。

使用 Connection 物件
 

雖然先前有定義如何讓 URL 提供 ExOLEDB 必需的資訊來建立連線,可能您會想要明確地開啟一個 Connection 物件,藉著開啟一個 Connection 物件,您可以:

  • 在資料夾階層中使用相對的 URL 來存取目前連線位置的相關資源。
     
  • 使用一個交易一次處理 Web 儲存系統中大量資源的更動。
     
  • 使用 Errors 集合物件在 ADO-provider 發生錯誤時將其捕捉,並在不停止程式執行下回復程式的正常執行。
     

要使用 SQL 來搜尋或查詢 Web 儲存系統,您必須開啟一個 Connection 物件。有關查詢 Web 儲存系統的資訊,本章稍後在 〈使用 SQL SELECT 陳述式來查詢 Web 儲存系統〉 一節中會有更詳盡的說明。

開啟與關閉連線
 

要開啟一個連線,您必須提供 OLE DB provider 的名稱以及可以指向您想連線的 Web 儲存系統的 URL。要連線至 Web 儲存系統,請設定 Connection.Provider 屬性為 ExOLEDB provider,即 ExOLEDB.datasource。接下來呼叫 Connection.Open 方法,並傳入字串型態的 URL 參數,此 URL 指向 Web 儲存系統的存放區。在您完成開啟連線的動作後,藉由呼叫 Connection 物件的 Close 方法,就可以關閉連線。

範例程式 4-1 說明如何建立一個 ADO Connection 物件、設定 Provider 屬性以及開啟連線。程式隨後會傳回一些有關現存連線的資訊,並會在結束前關閉 Connection 物件。


說明

本章所列的程式碼都是可執行的,您可以在本書所附光碟上的微軟 Visual Basic 專案 CH_04.vbp 中找到。如果您要執行範例程式,您必須先將 Zoo Management 這個範例程式安裝在您的 Exchange 2000 伺服器上。有關安裝資訊,請參閱 〈本書簡介〉 。此外,範例程式中經常呼叫一個名為 GetStorageName 的函式,此函式會傳回程式執行的網域名稱,有關此函式的資訊,請參閱 第八章〈與 Active Directory 互動〉 。


範例程式 4-1:與 Web 儲存系統資料夾連線
 

Sub ConnectToWSSFolder()
' By explicitly opening a conenction,
' you can use relative URLs, use single
' transactions, and trap OLE DB errors.
Dim cnn As ADODB.Connection
Dim strURL As String
' File URL to the Zoo Management application
strURL = GetStorageName & _
"applications/zoo management/"
Set cnn = New ADODB.Connection
With cnn
' Indicate the EXOLEDB provider
.Provider = "exoledb.datasource"
' Open the connection
.Open strURL
' Return some information about
' the connection.
Debug.Print "--------------------------------------"
Debug.Print _
"Current Connection Information"
Debug.Print _
"Command Timeout: " & .CommandTimeout
Debug.Print _
"Connection Timeout: " & .ConnectionTimeout
Debug.Print "--------------------------------------"
' Close the connection
.Close
End With
' Clean up
Set cnn = Nothing
End Sub

使用相對的 URL
 

當您以 Exchange 明確地建立了一個連線之後,您便可以使用相對的 URL。如果您正在開發 Web 應用程式,您一定已經對相對的 URL 有相當程度的認識。一個相對的 URL 是以一個已定義的絕對 URL 作為起始點,藉由與起始點間的相對關係來定位一個資源。例如,您可以用一個絕對 URL 來連線至資料夾:

File://./backofficestorage/domain.com/applications/zoo management/

接下來您便可以使用相對的 URL 來存取此資料夾中的子資料夾或項目。要從此點開始向下瀏覽整個樹狀結構,請以一個點和斜線作為 URL 的開始,並附上資源的路徑來建立一個相對的 URL。例如,要存取 Zoo Management 應用程式中的 Staff 子資料夾,您可以使用下列 URL:

./Staff/

您也可以使用相對的 URL 來向上瀏覽整個樹狀結構,請以兩個點和斜線作為 URL 的開始,並附加資源的路徑來建立一個相對的 URL,如果您只是要向上移動一層,便不需要附加資源的路徑。例如,要瀏覽 Zoo Management 應用程式的上一層,您可以使用下列的 URL:

../

範例程式 4-2 說明了如何配合 ADO 使用相對的 URL,在此程序藉由一個絕對 URL 連線到 Zoo Management 應用程式,而後便存取子資料夾和上一層資料夾。

範例程式 4-2 由連線至資料夾存取父資料夾與子資料夾
 

Sub UseRelativeURLs()
' By explicitly opening a connection to
' EXOLEDB, you can use realtive URLs to
' navigate to parent and child folders
' from the point of connection.
Dim cnn As ADODB.Connection
Dim strURL As String
Dim rec As ADODB.Record
' File URL to the Zoo Management application
strURL = GetStorageName & _
"applications/zoo management/"
Set cnn = New ADODB.Connection
With cnn
' Indicate the EXOLEDB provider
.Provider = "exoledb.datasource"
' Connect to the Zoo Management
' application folder
.Open strURL
End With
Set rec = New ADODB.Record
With rec
' Access the Staff child folder of
' the Zoo Management folder.
.Open "./Staff/", cnn
Debug.Print .Fields("DAV:href")
.Close
' Now access the parent folder of
' the Zoo Management folder.
.Open "../", cnn
Debug.Print .Fields("DAV:href")
.Close
End With
' Clean up
cnn.Close
Set rec = Nothing
Set cnn = Nothing
End Sub

使用 Transaction
 

當您使用 ADO 來更新一個資源時,此變更在您儲存此記錄時便會傳回 Web 儲存系統。每次當一個記錄被建立、更新或刪除時,這些改變將會一次一個傳回存放區,這種方式當然只有在少量記錄同時改變時才可被接受,如果您要更新大量的資料,這種方式會非常耗費伺服器的資源。Transaction 提供了另一種環境,將要對資料庫所做的所有更新動作暫存並一次同時執行,所有更新動作不是同時成功便是全部取消。

您必須使用 Connection 物件的 BeginTrans、CommitTrans 以及 RollbackTrans 方法來管理交易。要開始進行一個交易之前,您必須開啟一個 Connection 物件並呼叫 BeginTrans 方法,在您呼叫此方法後,所有的改變都不會馬上在存放區中反應。要在交易中儲存變更和結束交易,您必須呼叫 CommitTrans 方法;若要在交易中取消改變和結束交易,您必須呼叫 RollbackTrans 方法。範例程式 4-3 是交易範本。


說明

Exchange 2000 並不支援巢狀交易,您必須在開始新交易前,結束原有的交易。


範例程式 4-3:交易範本
 

Sub TransactionsTemplate()
' Turn on error handling
On Error GoTo HandleErrors
Dim cnn As ADODB.Connection
Dim strURL As String
' File URL to the Zoo Management application
strURL = GetStorageName & _
"applications/zoo management/"
Set cnn = New ADODB.Connection
With cnn
.Provider = "exoledb.datasource"
.Open strURL
End With
' Start caching changes
cnn.BeginTrans
'
' Make your record changes here
'
' Save the changes to the store
cnn.CommitTrans
ExitHere:
On Error Resume Next
cnn.Close
Set cnn = Nothing
Exit Sub
HandleErrors:
' Cancel the changes
cnn.RollbackTrans
Resume ExitHere
End Sub

錯誤控制
 

就像任何應用程式一樣,在 ADO 的運作過程中也會有錯誤發生,為了彰顯問題的嚴重性,一個單一的 ADO 錯誤可能引發多個 privider 的錯誤,這些錯誤實際上便是 privider 的錯誤而不是 ADO 的錯誤,會以 Error 物件儲存在 Connection 物件中的 Errors 集合物件裡。藉著建立捕捉 ADO 錯誤的機制,而後在 Errors 集合物件中尋找結果,您可以使用 Error 物件的屬性來判定產生 ADO 錯誤的原因,接著可以採取適當的動作來修復錯誤。最常使用的屬性列於表 4-1。

 表 4-1 常用的 Error 物件屬性 
屬性 說明 資料型態
Description String 字串型態的錯誤敘述
Number Long 長整數的錯誤代碼
Source Object 引發錯誤的物件

Errors 集合物件會保留錯誤,直到下一個執行成功的 ADO 作業程序清除此 Errors 集合物件為止。也就是說,如果您執行一個有填入 Errors 集合物件的 ADO 動作,而後又執行一個執行成功的 ADO 動作,原始的錯誤集合會被清除。要手動清除 Errors 集合物件,可以呼叫 Clear 方法。範例程式 4-4 說明了如何使用 Errors 集合物件。

範例程式 4-4:使用 Errors 集合物件來捕捉 ADO 呼叫所造成的錯誤
 

Sub TestErrors()
' This procedure forces ADO errors to be
' generated and then processes each one
' with an error handler.
' Turn on error handling
On Error GoTo HandleErrors
Dim strURL As String
Dim cnn As ADODB.Connection
' This is a bogus URL
strURL = GetStorageName() & "mbx/administrator"
Set cnn = New Connection
With cnn
.Provider = "exoledb.datasource"
' This line of code will trigger an error
.Open strURL
End With
ExitHere:
On Error Resume Next
cnn.Close
Set cnn = Nothing
Exit Sub
HandleErrors:
Dim objErr As ADODB.Error
Dim strError As String
' Loop through all of the errors
For Each objErr In cnn.Errors
' Get the error number, description, and source
strError = _
strError & "ADO error #" & _
objErr.Number & ": " & _
objErr.Description & vbCrLf & _
"Triggered by: " & _
objErr.Source & vbCrLf
Next
' Display the errors in a message box
MsgBox strError
Resume ExitHere
End Sub

使用 Record 物件
 

ADO Record 物件代表了 Web 儲存系統中的資源,例如資料夾、資料夾中的項目或是一個實際的檔案。Record 物件分為兩類:Collection Records 與 Non-collection Records,一個 Collection Record 可以是包含子資源的資料夾,而一個 Non-collection Record 則是一個在資料夾中的個別項目、一個結構化的文件或是一個文字檔案,Non-collection Records 物件是沒有子資源的。您可以使用 Record 物件在 Web 儲存系統中建立新資源或編輯既有的資源,本節將說明如何使用 Open 方法、開啟資源、列舉屬性、儲存 record、建立資源及附加自訂屬性於資源之中。

使用 Open 方法
 

您可以使用 Open 方法將 Web 儲存系統資源開啟為 Record 物件,也可以使用 Open 方法建立新資源,例如資料夾與項目。Open 方法的語法如下:

record. open[Source][, ActiveConnection][, Mode][, CreateOptions]
[, Options][, UserName][, Password]

參數用法:

record
一個 ADO Record 物件。

Source
要被開啟的資源的 URL。

ActiveConnection
選擇性參數,指出被開啟的 record 所透過的 connection。

Mode
選擇性參數,指出資源將如何被開啟:唯讀、可讀寫、可共享存取、不可共享存取等等。Mode 參數將在稍後 
〈認識 Mode 參數〉 一節中有更深入的介紹。

CreateOptions
選擇性參數,指出如果需建立資源時,資源將如何被建立。CreateOptions 參數將在稍後 〈認識 CreateOptions 參數〉 一節中有更深入的介紹。

Options
選擇性參數,指出正在開啟 record 的額外選項:非同步地開啟記錄或不使用相關的 stream 物件。ExOLEDB 只支援非同步地開啟記錄(adOpenAsync)。

UserName
選擇性參數,指出用來存取 Web 儲存系統的使用者 ID,在 ExOLEDB 中,此參數是無效的。

Password
選擇性參數,指出用來存取 Web 儲存系統的使用者密碼,在 ExOLEDB 中,此參數是無效的。

了解 Mode 參數
 

ConnectModeEnum 列舉了 Mode 參數可使用常數,Mode 參數可被設定為列於表 4-2 中的常數或其搭配組合。如果此參數沒有被設定,預設值為 adModeRead。

 表 4-2 列舉 Mode 參數 
常數 說明
adModeUnknown 0 未知的狀態。
adModeRead 1 用戶端可以讀取既有的值,但不能改變 record。
adModeWrite 2 用戶端可以改變 record,但不能讀取既有的值。
adModeReadWrite 3 用戶端可以讀取既有的值,也可以改變record。
adModeShareDenyRead 4 其他使用者在 record 被開啟時,不能讀取 record。
adModeShareDenyWrite 8 其他使用者在 record 被開啟時,不能寫入 record。
adModeShareExclusive 12 其他使用者在 record 被開啟時,不能存取 record。
adModeShareDenyNone 16 其他使用者在 record 被開啟時,可以讀寫 record。
adModeRecursive 4194304 用戶端會存取目前 record 的所有子 record。

了解 CreateOptions 參數
 

CreateOptions 參數決定了 ADO 如何開啟 record 以及是否要建立新的 record,此參數可被設定為一個或多個表 4-3 中的常數。要組合這些常數可使用 Or 運算元或加號(+)。

 表 4-3 列舉 CreateOptions 參數 
常數 用途 說明
adFailIfNotExists -1 Existing 如果 URL 無效,開啟便會失敗,此為預設值。
adOpenIfExists 33554432 Existing, New 如果資源存在,Record 才會被開啟,不會產生錯誤。
adCreateNoneCollection 0 New 建立一個項目,例如電子郵件訊息或約會。
adCreateCollection 8192 New 建立一個資料夾。
adCreateOverwrite 67108864 New 如果 URL 指定的資源已經存在此資源會被刪除,而新的資訊會存到 URL 所指定的位置。

以下列出一些使用 CreateOptions 參數的方法:

  • 要開啟項目或資料夾,便不用設定此參數。如果 URL 指定的資源不存在,程式將產生可捕捉的錯誤。
     
  • 要建立一個資料夾,設定此參數為 adCreateCollection。
     
  • 要建立一個項目,設定此參數為 adCreateNonCollection,或讓此參數為空值。
     
  • 要以新資訊取代既有的資料夾或項目,且目的是資料夾時,設定此參數為 adCreateCollection + adCreateOverwrite;若目的是項目時,設定此參數為 adCreateNonCollection + adCreateOverwrite。
     
  • 如果您要資料夾或項目已存在時才開啟,不存在時便將之建立,目的是資料夾時,設定此參數為 adCreateCollection + adOpenIfExists;目的是項目時,設定此參數為 adCreateNonCollection + adOpenIfExists。
     

開啟資源
 

您可以使用 Record 物件的 Open 方法來開啟一個單一資源,例如一個資料夾或是項目。若要以唯讀模式開啟資源,只要傳入指向此資源的 URL,如果您想改變 Record 的內容,必須以可讀取的權限來開啟。要開啟資料夾與項目來編輯時,請傳遞 adModeReadWrite 常數作為 Record.Open 方法的參數:

rec.Open urlResource, , adModeReadWrite

範例程式 4-5 說明了如何以唯讀模式開啟一個 Exchange 項目、傳回一些項目的資訊和傳回一些代表此項目之 ADO Record 物件的資訊。

範例程式 4-5:以唯讀模式在 Web 儲存系統中開啟一個資源
 

Sub OpenItem()
' Open an item in a Web Storage System
' and return the content class.
Dim urlResource As String
' URL to an item in the Zoo Management application
urlResource = GetStorageName() & _
"Applications/Zoo Management/Announcements/Welcome.eml"
With New ADODB.Record
' Open the item read-only
.Open urlResource
' Some info on the Exchange item
Debug.Print .Fields("DAV:displayname")
Debug.Print .Fields("DAV:contentclass")
Debug.Print .Fields("DAV:href")
' Some info on the ADO Record
Debug.Print .RecordType
Debug.Print .State
Debug.Print .ParentURL
' Close the object
.Close
End With
End Sub

列舉屬性
 

在使用 Record 物件開啟一個資源後,便可以讀取和設定所有儲存在其中的屬性。您可以藉由 ADO Fields 集合物件來存取與資源相關的結構描述屬性,也可以使用 Fields 集合物件來讀取屬性、設定屬性和得到更多關於資源的資訊,這些都可以藉由列舉整個 Fields 集合物件來達成。

Fields 集合物件相當於許多個別的 ADO Field 物件,一個 Field 物件代表著一個結構描述屬性。結構描述屬性可以是內含單一值(single-valued)或多重值(multi-valued),內含單一值的屬性是最普遍的屬性型態,此種屬性只能內含一個值,而多重值的屬性型態就沒有這麼普遍,其可以內含多個值,這些值以陣列形式存在。

要在 Record 物件的 Fields 集合物件中列舉出所有的屬性(包含單一或多重值),您可以使用 For..Next 迴圈。For..Next 迴圈會參考集合物件中的每一個物件,這代表您可以個別調查每一個物件。以本例而言,For..Next 迴圈會存取與資源相關的所有屬性,而後便可以使用 Field 物件的 Name 屬性傳回結構描述屬性的名稱。

以下的範例程式便是用迴圈在 Fields 集合物件中,用 IsArray 函式為每一個 Record 物件的屬性做檢查並傳回屬性的值。如果屬性包含多重值,IsArray 函式會傳回 TRUE。如果屬性包含單一數值,則程式會傳回屬性的名稱及[SINGLE-VALUED],如果屬性包含多重值的,則程式會傳回屬性的名稱及[MULTI-VALUED]。

For Each fd In rec.Fields
If Not IsArray(fd.VAlue) Then
Debug.Print fd.Name, "[SINGLE-VALUED]"
Else
Debug.Print fd.Name, "[MULTI-VALUED]"
End If
Next fd

由於 Web 儲存系統不是結構化的資料庫,每一個資源皆可以有不同集合的屬性。因此,一個 Record 的 Fields 集合物件不見得符合另一個 Record 的需求。

讀取單一值的屬性
 

要回傳並設定一個結構描述屬性值時,必須使用 Field 物件的 Value 屬性。而要讀取並設定單一數值屬性的數值,您並不需明確地呼叫 Value 屬性,因為 Value 屬性是 Field 物件的預設屬性,這代表著您不必指定 Field 物件的屬性數值,Value 屬性預設便會被設定並回傳。如果要讀取多重值屬性的值,就必須明確地呼叫 Value 屬性(請參閱稍後〈讀取多數值的屬性〉一節)。要確保兩種屬性型態的一致性,建議您一律呼叫 Value 屬性。例如,前一個範例程式已經改為會傳回單一數值的屬性的數值:

For Each fd In rec.Fields
If Not IsArray(fd.VAlue) Then
Debug.Print fd.Name, fd.Value
Else
Debug.Print fd.Name, "[MULTI-VALUED]"
End If
Next fd

讀取多重值的屬性
 

您可以藉由呼叫 Field 物件的 Value 屬性來讀取單一數值屬性;但是,您不能用相同的方式來讀取多重值的屬性。一個用來讀取多重值屬性的方式就是使用 For Each..Next 迴圈來列舉陣列中的各個屬性值,例如下列範例程式會用迴圈列出每一個位於 urn:schemas-microsoft-com:xml-data#element 結構描述屬性中的值:

For Each v In
rec.Fields(urn:schemas-microsoft-com:xml-data#element ").Value
Debug.Print v
Next v

如果加入這段程式到前一個範例中,此範例便具備了列舉多重值屬性之值的能力:

For Each fd In rec.Fields
If Not IsArray(fd.VAlue) Then
Debug.Print fd.Name, fd.Value
Else
Debug.Print fd.Name, "[MULTI-VALUED]"
For Each v In	fd.Value
Debug.Print v
Next v
End If
Next fd

儲存 Record
 

如果您對一個使用 Fields 集合物件來開啟 Record 物件的內容做更新時,就必須明確地儲存這些修改。當您開啟一個資源來編輯時,您並沒有與資源直接連線,資源中的屬性都從 Web 儲存系統複製到 ADO 物件執行個體中,任何您對物件所做的更新都只作用於本機的複本之中。要將這些更新的內容存回 Web 儲存系統中,必須針對更新的 ADO 物件呼叫 Fields.Update 方法。如果您沒有呼叫 Fields.Update 方法,沒有任何錯誤會發生,但是這些更新的內容就不會被儲存回 Web 儲存系統中,屬性的內容還是與物件被開啟時一樣。

當您使用 Record 物件在 Web 儲存系統中建立新資源時,並不需要呼叫 Fields.Update 方法,但是如果您使用 Fields 集合物件對資源做了任何更新動作,就需要呼叫 Fields.Update 方法來儲存這些更新的內容。


說明

要將 ADO 物件中的資源屬性內容更新為 Web 儲存系統中的最新版本,請呼叫 Resync 方法。


建立資源
 

要在 Web 儲存系統中建立新資源時,您需要使用 Open 方法,並傳入適當的 CreateOptions 參數來指出您要建立的是資料夾還是項目,以及如何將之建立。如果您立即要使用 Fields 集合物件對新資源作更新,就必須藉由傳遞 adModeReadWrite 作為 Mode 參數,使 Record 物件在開啟時便具備了被讀寫的權限。

下列是使用 ADO Record.Open 方法來建立新資源的一些方式:

  • 建立資料夾:

     
    rec.Open urlResource _
        , _
        , adModeReadWrite _
        , adCreateCollection
  • 建立項目:

     
    rec.Open urlResource _
        , _
        , adModeReadWrite _
        , adCreateNonCollection
  • 用新資訊取代既有的項目:

     
    rec.Open urlResource _
        , _
        , adModeReadWrite _
        , adCreateNonCollection + adCreateOverwrite
  • 開啟既有的資料夾,或建立不存在的資料夾:

     
    rec.Open urlResource _
        , _
        , adModeReadWrite _
        , adCreateCollection + adOpenIfExists

建立資料夾
 

當您在 Web 儲存系統中使用 ADO 建立新資料夾時,此資料夾會被預設為一個郵件資料夾。如果您要為一個特定內容類別建立資料夾,就必須明確設定 DAV:contentclass 結構描述屬性為適當的內容類別。例如,範例程式 4-6 說明了如何建立一個新資料夾來儲存 Zoo Management 應用程式的連絡人資訊,如果此資料夾已經存在,它會被新的資料夾資訊所取代。

範例程式 4-6:建立一個新的連絡人資訊資料夾
 

Function CreateFolder()
' Create a new contacts folder in the
' Applications folder tree.
Dim urlNewFolder As String
'URL to the new folder
urlNewFolder = GetStorageName & _
"applications/zoo management/new contact folder/"
With New ADODB.Record
' Create a new folder resource
' You must open the Record with Read/write permissions
.Open urlNewFolder _
, _
, adModeReadWrite _
, adCreateCollection + adCreateOverwrite
' Specifically create a contacts folder
' Otherwise, the folder would be a generic
' message folder.
'.Fields("dav:contentclass") = _
"urn:content-classes:contactfolder"
' Save the resource to the WSS
'.Fields.Update
End With
Debug.Print "Folder created."
End Function

建立項目
 

當您在 Web 儲存系統中使用 ADO 建立新項目,此項目會被預設為一個郵件項目。如果您建立不同類型的項目,必須明確設定 DAV:contentclass 結構描述屬性為適當的內容類別。

範例程式 4-7 說明了如何在資料夾中建立一個新的連絡人資訊,此資料夾是上一個範例程式中的 CreateFolder 程序所建立。如果此連絡人資訊已經存在,它會被新的連絡人資訊所取代。

範例程式 4-7:在公用資料夾中建立一個新的訊息項目
 

Sub CreateItem()
' Create a new contact in the folder
' created by the CreateFolder procedure.
Dim urlNewItem As String
'URL to the new message
urlNewItem = GetStorageName & _
"applications/zoo management/new contact folder/Robert Brown.eml"
With New ADODB.Record
' Create a new folder resource
' You must open the Record with Read/write permissions
.Open urlNewItem _
, _
, _
, adCreateNonCollection + adCreateOverwrite
' If you don't set this, you get a message by default
.Fields("dav:contentclass") = "urn:content-classes:person"
' Save the contact to the WSS
.Fields.Update
End With
Debug.Print "Contact created."
End Sub

為資源自訂屬性
 

用於特定用途的資料夾與項目通常需要針對其用途定義自訂的屬性,藉由使用自訂屬性,您可以儲存應用程式的特定資訊。例如,使用於 Zoo Management 應用程式的項目與資料夾,便使用了儲存動物園重要資訊的屬性。您可以在結構描述中定義自訂的屬性(請參閱 第三章〈Web 儲存系統結構描述〉 )或為每一個資源建立所需的新屬性。

要為資源建立自訂屬性,請附加新屬性於 Record 物件的 Fields 集合物件中,並同時呼叫 Fields.Append 方法來設定屬性值,這樣新屬性與內含值便會隨著資源儲存到 Web 儲存系統之中。Append 方法的語法如下:

Sub Append(Name As String, Type As DataTypeEnum[, DefinedSize As Long]
[, Attrib As FieldAttributeEnum = adFldUnspecified][, FieleValue])

要使用 Append 方法,您必須提供屬性名稱、ADO 資料型態與屬性的值。下列程式附加了一個叫做 Specialty 的字串屬性並設定屬性值為 Amphibians。

rec.Fields.Append "Specialty", adBSTR, , , "Amphibians"

當您建立一個資源的新屬性時,此屬性在預設上並不會附加於其他的資源,您必須附加此屬性給每個需要此屬性的資源。

範例程式 4-8 說明如何在連絡人資訊資料夾中建立連絡人資訊,這與前一節中 CreateItem 程序的建立方式相同,然而這一次自訂屬性 Specialty 會被附加於連絡人資料的記錄中,此屬性如同預先定義的屬性會一起隨著資源被儲存。

範例程式 4-8:以自訂屬性建立連絡人資訊
 

Sub CreateItemWithCustomProperty()
' Create a new contact with a custom property
' in the folder created by the CreateFolder procedure.
Dim urlNewItem As String
'URL to the new message
urlNewItem = GetStorageName & _
"applications/zoo management/new contact folder/Robert Brown.eml"
With New ADODB.Record
' Create a new folder resource
' You must open the Record with Read/write permissions
.Open urlNewItem _
, _
, adModeReadWrite _
, adCreateNonCollection + adCreateOverwrite
' If you don't set this, you get a message by default
.Fields("dav:contentclass") = "urn:content-classes:person"
' Create a custom property
.Fields.Append "Specialty", adBSTR, , , "Amphibians"
' Because this propert is a string value,
' you could use this code instead and get the
' same result.
'.Fields("Specialty") = "Amphibians"
' Save the contact to the WSS
.Fields.Update
End With
Debug.Print "Contact created."
End Sub

認識 ADO 的資料型態
 

當您為資源附加新屬性時,必須傳一個 DataTypeEnum 中的列舉常數作為 Type 參數。DataTypeEnum 中列舉了新欄位的 ADO 資料型態。表 4-4 列出最常用的型態,完整的範例程式請參閱《Microsoft Platform SDK》。

 表 4-4 DataTypeEnum 的數值 
常數名稱 說明
adArray 0x2000 必須與另一個資料型態常數結合使用,用來判斷此資料型態是否為陣列的旗標值。
adBigInt 20 8 位元組的整數。
adBinary 128 二進位值。
adBoolean 11 布林值。
adBSTR 8 以null結尾的字串(Unicode)。
adChar 129 字串。
a dCurrency 6 具有四位小數點的貨幣數值。
adDate 7 以倍精確度浮點數儲存的日期值。
adDecimal 14 精確的十進位的數值。
adDouble 5 倍精確度浮點數值。
adEmpty 0 空值。
adError 10 32 位元的錯誤碼。
adInteger 3 4 位元組且有正負號的整數。
adNumeric 131 有固定精確度及進位法的數值。
adSingle 4 單精確度浮點數。
adSmallInt 2 2 位元組且有正負號的整數。
adTinyInt 16 1 位元組且有正負號的整數。
adUnsignedBigInt 21 8 位元組且無正負號的整數。
adUnsignedInt 19 4 位元組且無正負號的整數。
adUnsignedSmallInt 18 2 位元組且無正負號的整數。
adUnsignedTinyInt 17 1 位元組且無正負號的整數。
adUserDefined 132 使用者定義的變數。
adWChar 130 以 null 結尾的 Unicode 字串。

使用 Recordset 物件
 

您可以使用 Recordset 物件存取 Web 儲存系統中的集合資源(group of resource),這些資源可以是資料夾中的內容、一群特定的項目或是資料夾與項目的組合。例如,Recordset 物件可以儲存收件匣中的內容或公用資料夾名稱的清單。Recordset 物件本身是由行(column)與列(row)所組成,行代表包含資料的眾多欄位,而列就是每一筆個別的記錄。Recordset 物件使用了一個用來控制瀏覽其中 record 的瀏覽狀態游標(cursor),雖然 Recordset 物件可以儲存多列記錄,但游標一次只能指向一列。本節將介紹如何開啟 Recordset 物件、在 Recordset 物件中移動以及使用 Recordset 物件來取得資料夾的內容。

開啟 Recordset
 

您可以使用多種不同的 ADO 物件開啟 ADO Recordset,例如使用下列方式:

  • 使用 Record 物件的 GetChildren 方法,從 Record 物件開啟 Recordset 物件。
     
  • 使用 Recordset 物件的 Open 方法來開啟 Recordset 物件。
     
  • 使用 Connection 物件的 Execute 方法,從 Connection 物件開啟 Recordset 物件。
     
  • 使用 Command 物件的 Execute 方法,從 Command 物件開啟 Recordset 物件。
     

當您使用 ExOLEDB provider 來開啟 Recordset 物件時,Recordset 物件會採用樂觀鎖定(optimistic locking)與一個動態的游標類型(dynamic cursor type)。在 樂觀鎖定 之中,使用者可以隨時對游標所指的列進行修改,除非此記錄正在呼叫 Fields.Update 方法進行儲存,此時 record 不能被其他使用者所存取。您可以使用動態類型的游標來往前或往後瀏覽 Recordset 中各列的資料,也可以改變現存的 record、增加與刪除 record。雖然其他的 ExOLEDB provider 允許您指定其他的鎖定選項及游標類型,但是 ExOLEDB 並不支援其他的選項。

使用 GetChildren 方法
 

呼叫 Record 物件的 GetChildren 方法將會建立一個將之視為 Record 物件其子 record 的 Recordset 物件。子 record 可以包含項目、子資料夾以及結構化的文件。例如,可以使用 GetChildren 方法來取得資料夾中的內容。要使用 GetChildren 方法,必須先開啟一個資源的 Record 物件,而後呼叫 Record.GetChildren 方法,Record 物件中的子 record 內容將會放置於新的 Recordset 物件中。

Dim rst As ADODB.Recordset
Set rst = rec.GetChildren

如果 Record 物件並無任何子 record,此方法會傳回一個空的 Recordset 物件。

使用 Recordset 物件的 Open 方法
 

您也可以使用 Recordset 物件的 Open 方法來開啟 Recordset 物件,Recordset 物件的 Open 方法語法如下:

Recordset .Open[Source][, ActiveConnection]
[, CursorType][, LockType][, Options]

若要使用 Open 方法從 Web 儲存系統中取得一群資源,您必須指定 Source 參數與 ActiveConnection 參數。Source 參數是指定 Recordset 物件各列的資料來源,如一段 SQL 字串;而 ActiveConnection 參數則指定了執行查詢時使用的連線。例如,下列範例程式建立並開啟了一個 Recordset 物件:

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open strSQLStatement, cnn

所有 Recordset.Open 方法的參數都是選擇性的,因為這些參數也都是 Recordset 中既存的屬性,您可以先設定這些屬性,再呼叫 Open 方法並不帶任何參數,下列範例程式與前一個程式的結果是相同的:

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
With rst
.ActiveConnection = cnn
.Source = strSQLStatement
.Open strSQLStatement
End With

雖然第二個範例程式行數較多,但您可以發現比起將這些值作為 Recordset.Open 方法的參數傳回,利用程式設定屬性值要容易許多。

瀏覽 Recordset
 

要瀏覽 Recordset 中的各列資料,您可以使用以下任何一個 ADO 提供的方法:MoveFirst、MoveNext、MovePrevious 與 MoveLast。每一個方法的名稱都清楚地說明其相對應的功能,您可以使用這些方法與 Recordset 的兩個屬性— BOF 與 EOF—來瀏覽一個 Recordset 物件。當游標位置在第一筆 record 之前時,BOF 屬性會是 TRUE,而游標位置在最後一筆 record 之後時,EOF 屬性會是 TRUE,如果 BOF 與 EOF 同時為 TRUE ,代表此 Recordset 物件是空的。圖 4-4 說明了游標位置在舉例的 Recordset 中,何時 BOF 與 EOF 會被設為 TRUE。若目前游標位置在 Record 1,如果游標向上移動一筆 record,BOF 就會被設為 TRUE;若目前游標位置在 Record 3,如果游標向下移動一筆 record,則 EOF 就會被設為 TRUE。


 

 圖 4-4 瀏覽 Recordset 物件時,可以使用 BOF 與 EOF 屬性來決定 record 游標是否已經 移至最前面或最後面

要瀏覽 Recordset 的每一筆 record,可以使用 Do...Loop 語法並將 Until 子句的條件設定為當 EOF 屬性值為 TRUE 時,這樣就可以讀取每一個資料列,直到沒有資料可讀為止,這種方式可以避免在讀取只有一筆資料列的 Recordset 物件時所會產生的錯誤。藉由這個迴圈,您可以讀取、設定屬性及執行需要的程序,在您呼叫 Loop 陳述式之前,請先確定您已經呼叫了 MoveNext 方法來使游標移至下一筆 record,如果沒有呼叫將會導致一個無窮迴圈。

下列範例程式說明了如何瀏覽 Recordset 的每一筆 record:

Do Until rst.EOF
'Print the display name of each record
Debug.Print rst.Fields("DAV:displayname")
'Move to next record
rst.MoveNext
Loop

使用 ADO 來取得資料夾的內容
 

在了解使用 Recordset 物件的基本方法後,便可以準備使用這些方法來讀取資料夾的內容。您可以使用 Record 物件、Record.GetChildren 方法與 Recordset 物件來讀取資料夾的內容,在使用了 Record 物件存取了父資料夾後,便可以呼叫 GetChildren 方法將要讀取的資料夾內容填入 Recordset 物件中,接著便可以使用迴圈來讀取 Recordset 物件中每一列 record 的內容。

範例程式 4-9 說明了如何開啟 Zoo Management 應用程式資料夾,並讀取其中每一列 record 的 DAV:href 屬性值。

範例程式 4-9:取得資料夾的內容
 

Sub OpenFolderAndContents()
' Reads the contents of a folder,
' inlcuding subfolders, items, and
' any structured documents.
Dim rec As ADODB.Record
Dim rst As ADODB.Recordset
Dim urlFolder As String
'Build the URL
urlFolder = GetStorageName() & _
"Applications/Zoo Management/"
'Create a Record object
Set rec = New ADODB.Record
'Open the Zoo Management application folder
rec.Open urlFolder
'Extract the contents of the folder
Set rst = rec.GetChildren
' Read the URL for each child record:
Do Until rst.EOF
Debug.Print rst.Fields("DAV:href")
rst.MoveNext
Loop
'Close the objects and release memory
rst.Close
rec.Close
Set rst = Nothing
Set rec = Nothing
End Sub

使用 SQL SELECT 陳述式來查詢 Web 儲存系統
 

當使用 Record 物件的 GetChildren 方法取得資料夾的內容時,便已取得所有的子 record,包含項目與其他的資料夾,同時也取得了每一個子 record 的所有屬性。但是否您只需要一部份的 record 或只需要所有 record 的一個屬性而已呢?解決這種問題的方法便是建立一個 SQL 查詢陳述式,您可以使用查詢陳述式在公用 Web 儲存系統或信箱的存放區內進行搜尋。Exchange 支援下列幾種 SQL 命令,包含:SELECT、WHERE、ORDER BY、GROUP BY 及 CONTAINS,然而 Exchange 並不支援一些結構化資料庫專用的 SQL 命令,例如:JOIN、MAX、MIN 或是 SUM 之類的命令。

要在 Exchange 存放區內查詢資料,您必須明確地與 Web 儲存系統連線,您可以使用 Connection 或 Command 物件來執行查詢陳述式,通常這種查詢陳述式是為了執行新增或刪除 record 這類的動作。如果需要對搜尋結果再做處理,請明確開啟一個 Recordset 物件,並傳入 SQL 陳述式作為資料來源。本節將說明如何使用 AddQuotes 函式、建立簡單的 SQL 陳述式、以查詢結果開啟 Recordset ,並將 Recordset 儲存為 XML 格式。

使用 AddQuotes 函式
 

SQL 查詢陳述式需要將其中的字串用引號括起來,您需要用引號將要查詢的 URL 括起來,屬性名稱與字串型態的屬性值也是一樣需要使用引號。將引號加入字串會使得 SQL 陳述式令人困擾,同時也許會花許多時間在決定整個陳述式到底需要幾個引號。

為了簡化程式的寫作,您可以使用一個函式來為字串加上引號。本書中皆使用一個名為 AddQuotes 的函式(參考範例程式 4-10)來完成這些程序,此函式接受一個名為 strValue 的參數,這也就是您想要加入引號的字串,如果此字串本身已含有引號,這些引號會被重覆再加一個。

範例程式 4-10:任何傳入此函式的字串會被加上引號
 

Public Function AddQuotes(strValue As String) As String
' Given a string, wrap it in quotes, doubling
' any quotes within the string.
Const QUOTE = """"
AddQuotes = QUOTE & _
Replace(strValue, QUOTE, QUOTE & QUOTE) & QUOTE
End Function

建立簡單的 SQL 陳述式
 

要從 Web 儲存系統中讀取 record,可以使用 SELECT 陳述式以及需要的條件子句。每一個 SELECT 陳述式都有相同的基本元件或片語:

SELECT properties
FROM SCOPE datasource
[WHERE criteria]
[ORDER BY sort fields]

WHERE 與 ORDER BY 子句都是選擇性的,同時也都不是執行查詢時所必需的。然而,當您在 Web 儲存系統中作特定的查詢時,您會發現這兩個子句具有相當多的用途。您可以使用 WHERE 子句來過濾查詢結果,而 ORDER BY 子句可排序查詢的結果。

在您建立了查詢陳述式後,可以將之作為 Recordset 物件中 Open 方法的參數來執行查詢。本節將逐步地建立 SQL 查詢字串,如此您便可以重覆使用這些程式碼並將之替換為您所需要的值。

SELECT: 選擇要傳回的屬性
 

建立一個 SELECT 陳述式,要以 SELECT 命令開始,接著便指出要傳回的結果中要包含哪些欄位的資訊。

SELECT [Column1][As Alias], [Column2][As Alias],

Column1 與 Column2 是要傳回的結構描述屬性的名稱,As alias 讓您每一個屬性取一個別名,而不需要在程式中使用結構描述屬性的實際名稱,至於選擇所要傳回的屬性數目則沒有限制。

下列程式範例建立的 SELECT 陳述式在本節稍後會使用到,此陳述式在結果中只會傳回 DAV:displayname、DAV:contentclass 及 DAV:href 這些結構描述屬性。先前有提到,所有字串值包含屬性名稱,皆必須用引號括起來,因此每一個屬性名稱都會被傳入 AddQuotes 函式來加上引號:

strSQL = "Select " & _
AddQuotes("DAV:displayname") & ", " & _
AddQuotes("DAV:contentclass") & ", " & _
AddQuotes("DAV:href")

雖然應該避免在查詢中傳回所有的結構描述屬性,因為這些屬性的數量非常的多,但是 Exchange 支援了使用星號(*)來代表要傳回所有結構描述屬性的欄位:

SELECT *

FROM: 指定搜尋 record 的位置
 

SQL 陳述式的 FROM 子句用來指定所要搜尋的 record 的位置:

FROM SCOPE('[Shallow | Deep] Traversal Of """ & URL & """)

URL 指出查詢的起始點同時也是 Web 儲存系統中的一個資料夾,因為 Exchange 架構於階層式的樹狀結構上,所以您也必須指出要在樹狀結構中搜尋到多深入。搜尋深度必須在 FROM 子句中加入 SCOPE 陳述式來設定,同時也可以設定為 Shallow 或 Deep。Shallow 代表只在 URL 所指定的資料夾中搜尋(忽略子資料夾),而 Deep 代表會搜尋 URL 所指定的資料夾與其子資料夾。您只能對非 MAPI 的 Web 儲存系統以及信箱的存放區執行 Deep 搜尋,整個搜尋設定陳述式必須由單引號括起。

下列範例程式會改良前一個 SELECT 陳述式,在 Zoo Management 資料夾中進行 Shallow 搜尋。與屬性名稱一樣,整個 URL 必須由引號括起:

'Begin the search here
urlQueryFld = _
GetStorageName() & "applications/Zoo Management/"
' Select the properties to be returned
strSQL = "Select " & _
AddQuotes("DAV:displayname") & ", " & _
AddQuotes("DAV:contentclass") & ", " & _
AddQuotes("DAV:href")
' Indicate shallow or deep traversal
' and what URL to begin looking
strSQL = strSQL & _
" FROM SCOPE('SHALLOW traversal of " & _
AddQuotes(urlQueryFld) & "')"

此 SELECT 陳述式在 Zoo Management 資料夾中進行搜尋,並傳回資源的 DAV:displayname、DAV:contentclass 及 DAV:href 結構描述屬性。

WHERE: 篩選查詢結果
 

WHERE 子句是 SELECT 陳述式的選擇性條件子句,此子句會依據您所提供的條件來限制 Recordset 物件中的資料列能不能被傳回。如果沒有指定 WHERE 條件子句,在指定 URL 中的所有 record 都會被傳回,WHERE 子句的語法如下:

WHERE [Expression] And | Or [Expression]

Expression 是一個組合式字串,其中包含要檢查的屬性、比較運算元與所要搜尋的值。在 WHERE 子句中使用的屬性並不需要被包含於 SELECT 子句中,您可以在 WHERE 子句中使用許多組合的條件,各種條件要以 AND 或 OR 區隔。

例如,下列範例程式便是改良前一個 SELECT 陳述式,並指定一些條件來篩選查詢的結果,範例中的 WHERE 條件子句限制結果內資源的 DAV:isfolder 結構描述屬性必須為 TRUE,如此一來使結果只有子資料夾而不會有項目。再次強調,所有字串值皆必須使用引號括起來。

'Begin the search here
urlQueryFld = _
GetStorageName() & "applications/Zoo Management/"
' Select the properties to be returned
strSQL = "Select " & _
AddQuotes("DAV:displayname") & ", " & _
AddQuotes("DAV:contentclass") & ", " & _
AddQuotes("DAV:href")
' Indicate shallow or deep traversal
' and what URL to begin looking
strSQL = strSQL & _
" FROM SCOPE('SHALLOW traversal of " & _
AddQuotes(urlQueryFld) & "')"
' Build a filter
' This one restricts the results to folders
strSQL = strSQL & _
" WHERE (" & _
AddQuotes("DAV:isfolder") & " = True)"

這個 SELECT 陳述式在 Zoo Management 資料夾中進行搜尋,並只傳回資料夾資源的 DAV:displayname、DAV:contentclass 及 DAV:href 結構描述屬性。

ORDER BY: 為查詢結果排序
 

ORDER BY 子句也是 SELECT 陳述式的選擇性條件子句,您可以使用此子句依據內容中一個或多個欄位來為查詢結果做排序。ORDER BY 條件子句的語法如下:

Order By [[Fieldname]〔ASC | DESC〕,][[Fieldname]〔ASC | DESC〕, [...]]

Fieldname 指定了排序所依據的屬性名稱,而 ASC | DESC 則指定了升冪或降冪,如果沒有指定排序方向,結果就會是升冪排序,如果您要降冪排序,就必須使用 DESC 關鍵字。如果您要依據一個以上的屬性來排序,各個片語需以逗號隔開,結果將會先以第一個屬性來排序,而後第二個、第三個,以此類推。與 WHERE 條件子句一樣,使用於 ORDER BY 子句的欄位並不需要包含在 FROM 的欄位表中,如果欄位不包含在 FROM 的欄位表中,這些欄位便只是作為排序條件的依據而不會出現於結果之中。

下列範例程式會改良前一個 SELECT 陳述式,並指定要依據資料夾的顯示名稱作降冪排序。與之前一樣,所有屬性名稱都必須使用引號括起來。

'Begin the search here
urlQueryFld = _
GetStorageName() & "applications/Zoo Management/"
' Select the properties to be returned
strSQL = "Select " & _
AddQuotes("DAV:displayname") & ", " & _
AddQuotes("DAV:contentclass") & ", " & _
AddQuotes("DAV:href")
' Indicate shallow or deep traversal
' and what URL to begin looking
strSQL = strSQL & _
" FROM SCOPE('SHALLOW traversal of " & _
AddQuotes(urlQueryFld) & "')"
' Build a filter
' This one restricts the results to folders
strSQL = strSQL & _
" WHERE (" & _
AddQuotes("DAV:isfolder") & " = True)"
' Sort the results by the display name
' of the folder in descending order
strSQL = strSQL & _
" ORDER BY " & AddQuotes("DAV:displayname") & " DESC"

這個 SELECT 陳述式在 Zoo Management 資料夾中進行搜尋,並只傳回資料夾資源的 DAV:displayname、DAV:contentclass 及 DAV:href 結構描述屬性,同時將結果依據 DAV:displayname 屬性值作降冪排序。

以查詢結果開啟 Recordset
 

範例程式 4-11 說明了如何以前一節所建立的 SELECT 陳述式作為 record 來源來開啟一個 Recordset 物件,在此程序開啟一個 Connection 物件後,會建立了一個 SQL 陳述式並傳給 Recordset 物件的 Open 方法,此程序將傳回各資料夾的資訊。

範例程式 4-11:在 Zoo Management 應用程式資料夾中取得所有的子資料夾
 

Sub GetZooMgtSubfolders()
' Use a SQL SELECT statement
' to get the subfolders in the
' Zoo Management application.
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim urlQueryFld As String
Dim strSQL As String
'Build the URL string
urlQueryFld = _
GetStorageName() & "applications/Zoo Management/"
' Connect to the calendar URL
Set cnn = New ADODB.Connection
With cnn
.Provider = "exoledb.datasource"
.Open urlQueryFld
End With
' Select the properties to be returned
strSQL = "Select " & _
AddQuotes("DAV:displayname") & ", " & _
AddQuotes("DAV:contentclass") & ", " & _
AddQuotes("DAV:isfolder") & ", " & _
AddQuotes("DAV:href")
' Indicate shallow or deep traversal
' and what URL to begin looking
strSQL = strSQL & _
" FROM SCOPE('SHALLOW traversal of " & _
AddQuotes(urlQueryFld) & "')"
' Build a filter
' This one restricts the results to folders
strSQL = strSQL & _
" WHERE (" & _
AddQuotes("DAV:isfolder") & " = True)"
' Sort the results by the display name
' of the folder in descending order
strSQL = strSQL & _
" ORDER BY " & AddQuotes("DAV:displayname") & " DESC"
'Create a Recordset object
Set rst = New ADODB.Recordset
With rst
'Open Recordset based on the SQL string
.Open strSQL, cnn
End With
'Print the folder names to the debug window
Do Until rst.EOF
Debug.Print rst.Fields("DAV:displayname")
Debug.Print vbTab, rst.Fields("DAV:contentclass")
Debug.Print vbTab, rst.Fields("DAV:href")
Debug.Print vbTab, rst.Fields("DAV:isfolder")
rst.MoveNext
Loop
' Close the ADO object
rst.Close
cnn.Close
' Release memory used by object variables
Set rst = Nothing
Set cnn = Nothing
End Sub

將 Recordset 儲存為 XML 格式
 

ADO 2.5 的一個新功能就是可以將 Recordset 儲存為 XML 格式而成為 .xml 檔案或一個 Stream 物件。這表示 Recordset 物件可以像標準 HTML 文字一樣簡單地透過 HTTP 協定來傳輸。例如,您可以使用前一節的查詢陳述式來取得 Zoo Management 應用程式資料夾的內容,藉此建立一個可以立即在 Web 上共享的 XML 文件。

要儲存 Recordset 為 XML 格式,您可以呼叫 Record 物件的 Save 方法,將目的指定為檔案名稱或 Stream 物件並傳遞 adPersistXML 常數,下列範例程式會將 Recordset 儲存為 XML 檔案:

rst.Save "c:\MyXML.xml", adPersistXML

其結果是一個可以被 XML Document Object Model(XML DOM)開啟與讀取的 XML 檔案,要知道有關讀取 XML 更詳盡的資訊,請參閱 第十三章〈XML 與 Exchange〉 。

如果您加入了先前的程式碼到範例程式 4-11,結果會如圖 4-5 所示:


 

 圖 4-5 您可以將 Recordset 物件內容儲存為 XML 檔案

如果您想要直接傳送 XML 到 Stream 物件,請使用以下的程式碼:

Dim stm As New ADODB.Stream
rst.Save stm, adPersistXML

說明

XML 並不支援 Web 儲存系統使用的某些資料型態,因此您並不能使用一個 Recordset 傳回所有的屬性。


ADO 的更多功能
 

ADO 除了可以用在 Web 儲存系統內開啟與建立資源,還可以用來執行一些 record 的控制動作,例如複製、移動與刪除資源。本節還會說明如何使用 Stream 物件。

複製資源
 

要將資源從原先位置複製到另一位置,可以使用 CopyRecord 方法。Record 物件的 CopyRecord 方法可以將原先位置的資源複製後,再到另一位置建立一個相同的資源。CopyRecord 方法的語法如下:

Record.CopyRecord([Source],Destination
[,UserName][, Password][, Options][, Async])

要使用 CopyRecord 方法,您需要為欲複製的資源開啟一個 Record 物件,並傳入目的 URL,此 URL 必須包含新資源的資料夾路徑及 DAV:displayname 屬性,如果此 URL 已經存在一個資源,CopyRecord 方法會產生一個錯誤,但是您可以設定 Options 參數為 adCopyOverwrite 常數(1),以新資訊取代既有資訊。

範例程式 4-12 說明了如何使用 Record 物件的 CopyRecord 方法,將一個資料夾從原先位置複製到另一個位置,如果此 URL 已經存在一個相同的資料夾,該資料夾將會被取代。

範例程式 4-12:複製資源到其他位置
 

Sub CopyResource()
' Copies a folder from one
' location to another.
Dim urlCopyFrom As String
Dim urlCopyTo As String
' This is the URL to the resource to be copied
' This folder must already exist.
urlCopyFrom = GetStorageName & _
"applications/zoo management/surgery/"
' This is the URL to the new resource
urlCopyTo = GetStorageName & _
"applications/surgery/"
With New ADODB.Record
.Open urlCopyFrom
.CopyRecord , urlCopyTo, , , adCopyOverWrite
.Close
End With
End Sub

移動資源
 

要將資源從原先位置移動到另一個位置,可以使用 MoveRecord方法。Record 物件的 MoveRecord 方法實質上是將一個 URL 的資源刪除,並到另一個 URL 重新建立一個相同的資源。如果要移動的 record 是一個集合物件,所有此 record 的子 record 都會跟著一起移動。MoveRecord 方法的語法如下:

Record.MoveRecord ([Source],Destination,[UserName][, Password][, Options][,Async])

要使用 MoveRecord 方法,您需要為欲移動的資源開啟一個 Record 物件,此 Record 物件必須有讀寫的權限,因為 ExOLEDB 必須要能夠在來源的 URL 刪除原始的資源。目的 URL 必須包含新資源的資料夾路徑及 DAV:displayname 屬性,您可以指定與原來不同的 DAV:displayname 屬性來為資源更名。如果此 URL 已經存在一個資源,MoveRecord 方法會產生一個錯誤,您可以設定 Options 參數為 adMoveOverwrite 常數(1),以新內容取代既有的目的 record。

範例程式 4-13 說明如何使用 Record 物件的 MoveRecord 方法,將一個連絡人資訊從原先的資料夾搬移到另一個資料夾,如果此 URL 已經存在一個連絡人資訊,該連絡人資訊將會被取代。

範例程式 4-13:將一個連絡人資訊從原先的資料夾移動到另一個資料夾
 

Sub MoveResource()
' Moves a contact from one folder
' to another. You must open the
' resource read/write in order to get
' this to work.
Dim urlMoveFrom As String
Dim urlMoveTo As String
' This is the URL to the resource to be moved
' This folder and contact must already exist.
urlMoveFrom = GetStorageName & _
"applications/zoo management/announcements/Welcome.eml"
' This is the URL to the new resource
urlMoveTo = GetStorageName & _
"applications/zoo management/research/Welcome.eml"
With New ADODB.Record
' Open a record for the contact to be moved
' This must be opened read/write
.Open urlMoveFrom, , adModeReadWrite
' Move the contact to the new destination
' If it exists, overwrite with the new info
.MoveRecord , urlMoveTo
.Close
End With
End Sub

刪除資源
 

您可以使用 Record 或 Recordset 物件的方法,刪除 Web 儲存系統中的資源。您必須呼叫 DeleteRecord 方法,才能使用 Record 物件來刪除資源,您需要為欲刪除的資源開啟一個 Record 物件,該 Record 物件必須有讀寫的權限,接著便可以呼叫 DeleteRecord 方法。而 DeleteRecord 方法沒有任何參數。

如果使用 DeleteRecord 方法來刪除一個資料夾,所有在其中的項目與子資料夾也會被刪除。範例程式 4-14 的 DeleteAResource 程序可用於刪除資料夾與項目,此程序接受一個參數,也就是要刪除資源的 URL,如果資源成功地被開啟與刪除,DeleteAResource 會傳回一個成功訊息。

範例程式 4-14:刪除位於一個 URL 中的資源
 

Sub DeleteAResource(urlDelete As String)
' You can use this procedure to
' delete folders or items.
' Turn on error trapping for VB
' and for VBScript
On Error Resume Next
' Open the resource to be deleted
With New ADODB.Record
.Open urlDelete, , adModeReadWrite
If Err.Number <> 0 Then
' Record cannot be found
Debug.Print "Record does not exist."
Else
' Delete the resource
.DeleteRecord
If Err.Number <> 0 Then
' Unable to delete the record
Debug.Print _
"Problem deleting. Check permissions."
Else
Debug.Print "Record deleted."
End If
End If
' Close the record
.Close
End With
End Sub

如果您想從開啟的 Recordset 物件中刪除資源,先移動至欲刪除的項目,再呼叫 Recordset 物件的 Delete 方法,這樣並不會刪除 Recordset 物件,只會刪除目前的項目。

以 Stream 存取資源內容
 

您可以使用 Stream 物件以二進位資料流的形式,對資源內容進行存取,也可以使用 Stream 物件來開啟附件、存取部分的嵌入郵件與取得多媒體資料。本節將介紹如何開啟與讀取項目的預設 Stream 以及儲存資料流到一個檔案。

開啟與讀取項目的預設 Stream
 

在 Web 儲存系統內的每個項目都有一個針對存取項目 Stream 的特殊屬性,這個屬性稱為預設資料流(adDefaultStream),包含了一個任意長度的字元串列但只適用於 non-collection 的 record。您可以用與存取包含多值屬性相同的方式來存取該屬性,在開啟項目的 Record 物件後,呼叫 Field 函式並傳入 adDefaultStream 常數,在 Stream 開啟後,便可以使用 Read 或 ReadText 方法來讀取內容。Read 方法用來讀取二進位資料流,並以一個變數傳回結果,而 ReadText 方法則用來讀取文字資料流並以字串傳回結果。

下列範例程式存取了一個項目的 Stream 並以字串傳回內容:

rec.Open urlResource
Set stm = New ADODB.Stream
Set stm = rec.Fields(adDefaultStream).Value
Debug.Print stm.ReadText

說明

Exchange 內的 CDO 使用 GetStream 方法來開啟一個物件的預設 Stream。


儲存 Stream 到一個檔案
 

您可以使用 Stream 物件的 SaveToFile 方法,來將資料流的二進位內容儲存至指定位置的檔案之中。例如,您可以使用 SaveToFile 方法,來將訊息的附加內容儲存至一個檔案。SaveToFile 方法的語法如下:

Stream.SaveToFile FileName[,SaveOptions]

使用 SaveToFile 方法時,必須以字串型態提供新建立的檔案一個完整的檔案名稱,也可以傳入一個 SaveOptions 常數,adSaveCreateNotExist 常數(1)代表只有在檔案不存在時才建立新檔案,而 adSaveCreateOverwrite 常數(4)代表如果檔案存在則取代舊檔案。

範例程式 4-15 說明了如何在 Web 儲存系統中取得一個 Word 文件的預設 Stream,並儲存資料流於本地端的硬碟檔案中,且具備取代既有相同名稱檔案的功能。要執行此程序,您必須先將一個 Word 文件建立於 Web 儲存系統中。

範例程式 4-15:從 Web 儲存系統資料夾中複製一個 Word 文件到本地端的硬碟檔案中
 

Function GetStreamforWordDocument()
' Copies a Word document from a
' Web Storage System folder to
' the local disk.
Dim stm As ADODB.Stream
Dim urlResource As String
' URL to the document
urlResource = GetStorageName() & _
"applications/Zoo Management/Research/Demo.doc"
With New ADODB.Record
.Open urlResource
' Get the Stream for the Word document
Set stm = New ADODB.Stream
Set stm = .Fields(adDefaultStream).Value
' Save it to a file
stm.SaveToFile _
"c:\copy of demo.doc" _
, adSaveCreateOverWrite
End With
' Clean up
stm.Close
Set stm = Nothing
End Function

結合 ADO 與 Microsoft Internet Publishing Provider
 

本章都在介紹如何撰寫使用 ExOLEDB Provider 的 ADO 程式(程式只能在伺服器端執行),然而,這限制了您使用程式於伺服器端應用程式的彈性,例如使用 ASP 技術的 Web 應用程式或是 Web 儲存系統的事件。如果您要從微軟 Office 之類的用戶端應用程式使用 ADO 2.5 來存取 Web 儲存系統,您在用戶端機器上可以使用微軟 Internet Publishing Provider(MSDAIAPP)。MSDAIAPP 是使用 ExOLEDB之外的另一個選擇,可以在 Microsoft Windows 2000、Microsoft Window 95 及之後的版本與 Microsoft Windows NT 4.0 上執行,安裝 Microsoft Office 2000 時會一併安裝 Internet Explorer 5 或更新的版本,這意味著可以建立最適合您需求的用戶端應用程式。

如果您要使用 Microsoft Internet Publishing Provider 來建立應用程式,就必須在每一台用戶端電腦上安裝 ADO 2.5,ADO 2.5 會隨著 Windows 2000 自動安裝至系統中,如果您的用戶端電腦使用較早的 Windows 版本,就需要安裝 ADO 2.5。您可以下載這些 DLL 當作 Microsoft Data Access Components(MDAC)的一部份,並藉由您的組織將它們散發出去。MDAC 等於是最新版的 ADO、OLE DB 以及 Open Database Connectivity(ODBC),這些都是一起被釋出且有說明文件與支援的元件,最新的版本會放在 http://www.microsoft.com/data/ 。

Microsoft Internet Publishing Provider 註冊了 HTTP URL 名稱空間,並使用 HTTP/WebDAV 協定,因此必須為 ExOLEDB 建立所需要的不同 URL,您可以使用和 Internet Explorer 建立 Web 瀏覽器所用 URL 的相同方式,來建立 Microsoft Internet Publishing Provider 的 URL。在您建立適當的 URL 之後,您就可以使用本章之前所說明的方式,使用 ADO 來存取與控制項目。當您在程式中以 HTTP 使用 URL 時,OLE DB 會自動採用 Microsoft In4ternet Publishing Provider,因此不必明確指定一個 proivider。範例程式 4-16 說明如何使用 Microsoft Internet Publishing Provider 與 Web 儲存系統連線、開啟 Zoo Management 應用程式中的資料夾以及傳回每一個子資料夾的資訊。

範例程式 4-16:使用 Microsoft Internet Publishing Provider 開啟 Zoo Management 應用程式中的資料夾
 

Sub OpenFolderContents_MSDAIPP()
' Use the Internet Publishing Provider
' to open a folder and return the URLs
' to each of the child folders.
Dim rec As ADODB.Record
Dim rst As ADODB.Recordset
Dim urlFolder As String
' Build the URL. Modify this for your
' own situation.
urlFolder = _
"http://cyberserver/zooweb/"
' Reference the folder
Set rec = New ADODB.Record
rec.Open urlFolder
' Get the folder contents
Set rst = rec.GetChildren
Do Until rst.EOF
Debug.Print rst.Fields("DAV:href")
rst.MoveNext
Loop
' Clean up
rst.Close
rec.Close
Set rst = Nothing
Set rec = Nothing
End Sub

本章總結
 

Exchange 2000 Server 使用 ADO 2.5 時,能輕易控制 Web 儲存系統中的資訊,如同使用其他資料庫軟體一樣。藉由 URL 便可快速地在存放區中找到特定的項目或資料夾,接著使用 Record 與 Recordset 物件來開啟、編輯、建立或刪除這些資源。而新的 Stream 物件也因為以 bits 型態控制標準的檔案作業程序,來取代以往使用大塊記憶體處理資源的方式,提升了處理的效率。甚至 SQL SELECT 陳述式也可以用在 Web 儲存系統中存取資訊。綜合所有功能,現在可以完全使用程式來控制 Web 儲存系統。

第五章〈介紹 Exchange 的 CDO〉將會介紹如何使用 Exchange 的 CDO 協同作業工具來擴充 ADO 的瀏覽功能。

posted on   Mint  阅读(1522)  评论(0编辑  收藏  举报
努力加载评论中...

点击右上角即可分享
微信分享提示