Office Space:撰寫 Microsoft Office 應用程式指令碼的秘訣

Office Space

歡迎蒞臨 Office Space 專欄,這裡提供處理 Microsoft® Office 應用程式指令碼的秘訣。每週二和週四我們將刊出新的秘訣,若要參閱以前討論過的秘訣,請造訪 Office Space Archive (Office Space 過往文件)。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

將連絡人資訊匯出到 Microsoft Excel

Microsoft Outlook 不僅是用來傳送、整理電子郵件,以及進行各種電子郵件相關動作絕佳的程式,更是方便存放連絡人資訊的地方。Outlook 不但可以匯入以「vCard」傳送的連絡人資訊、排序和搜尋連絡人,而且要是有適當的硬體,甚至還可以為您撥打個人電話。只要您是在 Outlook 內工作,這些都是很棒的功能。但要是您想在 Outlook 以外使用連絡人資訊呢?有沒有辦法可以快速又輕鬆地將連絡人資訊匯出到 Microsoft Excel 或其他一些程式呢?有沒有方法可以寫指令碼來進行呢?

總有一天,我們會提出像這樣的問題,答案會是「沒有」,然後這個專欄寫到那一行就停筆了,可惜那一天還沒來臨。今天的答案就跟往常一樣:當然有囉,方法既迅速又簡單,我們將在此示範。

可是每次都問這種設問法,不累嗎?換種寫作方法比較好吧。嘿!不打混了,還是言歸正傳。

將連絡人資訊匯出到 Excel 的秘密在於,先取得連絡人資訊,有了資訊,剩下的其實很簡單。所以,讓我們先想辦法從 Outlook 中擷取連絡人資訊,掌握該項工作之後,再來談將該項資訊寫入 Excel 試算表中。

注意:另外要提的是,今天的專欄以簡單為重:今天使用的指令碼只會提取出主要 [連絡人] 資料夾中的連絡人。要是 [連絡人] 資料夾中有子資料夾呢?今天的指令碼會忽略這種可能。要是 [連絡人] 資料夾中有通訊清單呢?今天的指令碼也會忽略這種情況,它不會嘗試擷取通訊清單中的所有名稱。這兩種都是實用的案例,不過我們現在只想把重心放在從連絡人清單抓取資訊的基本原理。其他的案例我們以後會提到。


這裡的指令碼會擷取 Outlook 通訊錄中所有連絡人的 FullNameBusinessTelephoneNumber 屬性:


On Error Resume Next

Const olFolderContacts = 10

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")

Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items

For Each objContact In colContacts
    Wscript.Echo objContact.FullName, objContact.BusinessTelephoneNumber
Next


指令碼開始會先定義一個名為 olFolderContacts 的常數,接著將值設為 10,我們會用這個常數來告知指令碼從 Outlook 的 [連絡人] 資料夾擷取資訊。接著會使用這行指令碼繫結到 Outlook 目前的執行個體 (這個指令碼假設 Outlook 已在執行中):


Set objOutlook = CreateObject("Outlook.Application")


與 Outlook 連線之後,接著會使用 GetNamespace 方法繫結到 MAPI 命名空間,這個命名空間 (實際上是您唯一能夠繫結的命名空間) 可讓我們使用 Outlook 中各種不同的物件,包括資料夾物件等。事實上,要擷取 [連絡人] 資料夾中所有連絡人的清單,使用這行程式碼就可以了:


Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items


我們在這裡做的是傳回連絡人集合,然後將該集合儲存到一個名為 colContacts 的變數中。您也看到我們呼叫 GetDefaultFolder 方法,將之前定義的 olFolderContacts 值傳遞給它。同時我們還要求 Items 屬性,這單純只是一份指定資料夾中所有項目的清單。因為是連接到 [連絡人] 資料夾,所以項目屬性會包括連絡人集合。

其餘的很簡單:建立 For Each 迴圈來循環處理集合,以回應本例中的連絡人的 FullNameBusinessTelephoneNumber。這麼做之後,會取得類似如下的資訊:


Ken Myer (410) 555-9683
Pilar Ackerman (425) 555-2005
Jonathan Haas (425) 555-5581


不賴吧?還有,不用多說,連絡人提供的屬性還不只 FullName 和 BusinessTelephoneNumber,如需完整清單,請參考 MSDN 上的 Microsoft Outlook VBA Language Reference (英文)。

好啦,好消息說完,現在要來報告壞消息。您可能已經注意到,我們在前一個指令碼中所回應的只有連絡人的名稱和電話號碼。只要回應的是非電子郵件屬性的值,就可以完全自動執行指令碼,但要是想回應連絡人的名稱和電子郵件地址,就得使用如下的程式碼:


For Each objContact In colContacts
    Wscript.Echo objContact.FullName, objContact.Email1Address
Next


這用指令碼辦得到嗎?可以,那可以完全自動執行嗎?不行,只要指令碼一嘗試存取 Email1Address 屬性,螢幕上就會出現下面的對話方塊:

Microsoft Outlook


您必須手動回答此對話方塊,指令碼才能繼續 (而且因為我們正在 For Each 迴圈中,要是您回答 [否],就必須針對清單中的每個連絡人回答此對話方塊。假使回答 [是],就會假設所有連絡人都選擇 [是])。如果不回答,則該對話方塊會逾時,而且指令碼就無法擷取電子郵件地址。

您可能已經猜到,這是 Outlook 內建的安全性功能,為的是要防止病毒傳送電子郵件給您所有的連絡人。當然也是要避免您開始指令碼之後離開,以為指令碼不需要任何使用者介入就會完成 (從好的一面看來,在您允許存取並按下 [是] 之後,指令碼就可以持續不中斷地執行)。我們今天不打算鑽研 Outlook 安全性功能的原因和理由,如需要詳細資訊,可參考 Microsoft Outlook 2003 SDK 的相關部份。只要記得,假使要擷取任何電子郵件相關的屬性,就必須處理這個對話方塊。

好吧,現在來談談將這項資訊匯出到 Excel。其實很簡單,我們今天不會詳述指令碼的 Excel 部分,如果您想知道將資料寫入 Excel 試算表的基本資訊,可以讀讀看 MSDN 上的Scripting Clinic (Scripting 門診) 專欄。下面的指令碼會將 FullName 和 BusinessTelephoneNumber 寫入 Excel 試算表:


On Error Resume Next

Const olFolderContacts = 10

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")

Set colContacts = objNamespace.GetDefaultFolder(olFolderContacts).Items

Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Add()
Set objWorksheet = objWorkbook.Worksheets(1)

objExcel.Cells(1, 1) = "Name"
objExcel.Cells(1, 2) = "Business Phone"

i = 2

For Each objContact In colContacts
    objExcel.Cells(i, 1).Value = objContact.FullName
    objExcel.Cells(i, 2).Value = objContact.BusinessTelephoneNumber
    i = i + 1
Next

Set objRange = objWorksheet.UsedRange
objRange.EntireColumn.Autofit


要是想包含的屬性不只有 FullName 和 BusinessTelephoneNumber 呢?也很簡單,只需要做兩件事。

第一,建立一些額外的欄名,例如,假設您想要包含 CompanyNameBirthday 屬性的話,設定欄名的程式碼看起來就會像:


objExcel.Cells(1, 1) = "Name"
objExcel.Cells(1, 2) = "Business Phone"
objExcel.Cells(1, 3) = "Company"
objExcel.Cells(1, 4) = "Birthday"


第二,必須將 CompanyName 和 Birthday 放入 For Each 迴圈中,這是您實際將資訊寫入試算表的迴圈。例如:


For Each objContact In colContacts
    objExcel.Cells(i, 1).Value = objContact.FullName
    objExcel.Cells(i, 2).Value = objContact.BusinessTelephoneNumber
    objExcel.Cells(i, 3).Value = objContact.CompanyName
    objExcel.Cells(i, 4).Value = objContact.Birthday
    i = i + 1
Next


執行指令碼後,應該會得到一個看起來像下面的試算表:

Microsoft Outlook


怎麼樣,很酷吧?

等一下,這不是設問性的問題,我們是真的想聽聽您的看法。嘿,等等,別走呀…

顯示: