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

Office Space

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

篩選 Microsoft Outlook 中的電子郵件

儘管身為 Microsoft Scripting Guys,我們不覺得寫程式可以解決人生所有難題 (可能可以解決大部分,但不可能全部)。講到系統管理,我們總認為最快最簡單的解決方案就是最好的。我們往往認為寫指令碼比使用命令列工具或圖形化使用者介面還要方便,但事實不盡然。只要使用者介面 (GUI) 比撰寫和使用指令碼還要快,何不使用 GUI 呢?(而且這樣我們就可以少寫一篇專欄啦!)

這一點在使用 Microsoft Outlook 時尤其適用。《Office Space》專欄很少討論 Outlook,有兩個原因:第一,Outlook 的使用者介面已經夠好了。第二,由於 Outlook 內已經新增了許多安全性功能,寫程式不一定是最快且最簡單的方法,而寫指令碼寫完還得維護。如果一定要替 Microsoft Outlook 轉寫指令碼,那一定是寫程式比使用者介面方便。

我們認為篩選電子郵件就是一個很好的時機。篩選出符合特定條件的電子郵件並加以處理,並不是什麼罕見的動作。舉幾個例子:您或許想把 [收件匣] 內從 Ken Myer 寄來的電子郵件都搬到另一個資料夾,或許您想找出所有標題為 Project Proposal 的郵件並列印出來,或許您想找出所有標示為待辦的電子郵件並放在一個 Word 文件裡。您可以透過使用者介面完成這些工作,或使用這簡單的指令碼辦到:


Const olFolderInbox = 6

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

Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[Subject] = 'Project Proposal'")

For Each objMessage In colFilteredItems
    objMessage.PrintOut
Next


這個指令碼會將標題為 Project Proposal 的電子郵件自動印出,方法是先定義一個叫做 olFolderInbox 的常數,然後將常數的值設為 6。我們會使用該常數告訴指令碼要繫結到哪個 Outlook 資料夾。 建立 Outlook.Application 物件的執行個體,然後使用 GetNamespace 方法連接到 MAPI 命名空間 (恰好是唯一可供繫結的命名空間)。接著呼叫 GetDefaultFolder 方法 (將常數 olFolderInbox 當作唯一的參數傳出),就此建立與 [收件匣] 的連線。

有了前面的準備,現在可以開始處理一些比較有趣的東西了。我們先使用這行程式碼傳回一個包含 [收件匣] 內所有項目的集合。


Set colItems = objFolder.Items


取得集合後,呼叫 Restrict 方法篩選出不符合指定條件的電子郵件。請注意,我們並不是把這些電子郵件從 [收件匣] 內刪除,而是抓出所有標題為 Project Proposal 的電子郵件,然後將它們放在一個名為 colFilteredItems 的新集合裡。方法是把電子郵件屬性 (Subject) 放在方括弧內,加上等號然後把目標主旨列放在單引號內。也就是:


Set colFilteredItems = colItems.Restrict("[Subject] = 'Project Proposal'")


如果只想找出 Ken Myer 送來的電子郵件?沒問題,方法大同小異:


Set colFilteredItems = colItems.Restrict("[From] = 'Ken Myer'")


方法是把電子郵件屬性 (From) 放在方括弧內,加上等號然後把目標主旨列放在單引號內。

那標示為待辦的郵件項目呢?請看看《Microsoft Outlook VBA Language Reference 》(英文) 中的MailItem 文件,您就會瞭解 FlagStatus 屬性是一個整數值。進一步研究 (英文) 會告訴您 2 代表郵件已標示為待辦 (提示:查詢常數 olFlagStatus 的列舉值)。程式碼如下:


Set colFilteredItems = colItems.Restrict("[FlagStatus] = 2")


請注意,2 這個值並沒有放在單括弧內。因為單括弧是用於字串值,數值和布林值並不需要單括弧。舉例來說,這個程式碼傳回尚未讀取的郵件集合:


Set colFilteredItems = colItems.Restrict("[Unread] = True")


還不賴吧?一般來說,如果是 MailItem 物件的屬性,就可供篩選。 您還可以合併篩選需求。舉例來說,您只想要找出 Ken Myer 寄來但尚未讀取的郵件,方法如下:


Set colFilteredItems = colItems.Restrict("[Unread] = True AND [From] = 'Ken Myer'")


這種情況下需要用到兩個篩選器:[Unread] = True 和 [From] = 'Ken Myer',然後再使用 AND 運算子合併這兩個篩選器就得了。

而找出來自 Ken Myer 或 Pilar Ackerman 的電子郵件方法又是:


Set colFilteredItems = colItems.Restrict("[From] = 'Ken Myer' OR [From] = 'Pilar Ackerman'")


反正您能夠意會就好。

最棒的地方其實不只是能傳回一組目標電子郵件,還能對整個集合執行動作。本指令碼範例中,我們使用 PrintOut 方法列印集合內的每一封電子郵件:


For Each objMessage In colFilteredItems
    objMessage.PrintOut
Next


您也可以把每個郵件放入 Word 或資料庫內,或在命令視窗內顯示每個郵件。方法很簡單,只不過是傳回 Body 屬性的值:


For Each objMessage In colFilteredItems
    Wscript.Echo objMessage.Body
Next


就是這麼簡單,現在您可以輕鬆快速地使用命令列讀取相關電子郵件啦!

附註:如果您要傳回郵件本文,則要處理出現的安全性對話方塊。


在這種時候使用指令碼的確比 Outlook 的使用者介面快多了 (感謝老天爺賜給我們發揮的機會,我們可不想丟飯碗)。雖然不能保證今天介紹的指令碼可以處理生命中所有的難題,但這並不表示它沒有這個潛力。說不定真有那麼一天...

顯示: