字體:小 中 大 | |
|
|
2009/06/18 02:37:44瀏覽9847|回應3|推薦17 | |
*這裡所說的 "Outlook" 是指 "Microsoft Office (我用的是2003版)" 裡的 Outlook,不是 Outlook Express。Outlook Express 不支援 VBA。
*2018/7/2補充說明:經查2007版的物件庫已變更。在2007版中,此程式裡的 Outlook.MAPIFolder 都必須改成 Outlook.Folder 有位朋友讀了「 把 email 附件檔全部存入一個資料夾」這篇文章,留言問道:『如果我不是使用預設的"收件匣",而是我自己建的郵件目錄,還能使用GetDefaultFolder()嗎?如果不行,那要如何取得這個資料匣內的郵件呢?』這是一個很好的問題。GetDefaultFolder() 只能用於 Outlook 預設的資料夾,傳回的一定是如:"收件匣"、"寄件匣"、"連絡人"......等等這些資料夾物件。對於一般資料夾 (包括 Outlook 預設的資料夾),可以用底下這樣來取得:
Set myNameSpace = Application.GetNamespace("MAPI")
For Each subFolder In myNameSpace.Folders If subFolder.Name = "個人資料夾" Then .........(對這個資料夾要做的處理) End If Next subFolder 或者像這樣:
Set myNameSpace = Application.GetNamespace("MAPI")
For i = 1 to myNameSpace.Folders.Count
If myNameSpace.Folders(i).Name = "個人資料夾" Then .........(對這個資料夾要做的處理) End If Next i 在 Outlook 裡的資料夾其實是樹狀的結構,而且允許使用者自建資料夾。myNameSpace.Folders是 Outlook "第一層資料夾" 組成的集合 (collection) 物件。myNameSpace.Folders.Count 是這個集合裡的資料夾總數。而像 myNameSpace.Folders(1)、myNameSpace.Folders(2)......就是這個集合裡的個別資料夾。
myNameSpace.Folders(i).Name 就是某個資料夾的名稱。在底下的程式裡,還會用到資料夾的.DefaultMessageClass這個屬性來判斷資料夾的類別。(.Name 和.DefaultMessageClass屬性值都是字串型態)
要存取使用者自建的資料夾,就必須面對多層資料夾的問題,因為使用者自建的資料夾,不確定在第幾層 (不可能是第一層資料夾)。在前述「 把 email 附件檔全部存入一個資料夾」那篇文章裡,我為了降低程式的複雜度,刻意迴避了資料夾樹狀結構問題。在另一篇「 快速的把讀取窗格全部關掉」裡,您就會看到我用遞迴呼叫的方法來解決樹狀結構 (多層資料夾) 的問題。
底下我用實例來示範以 Msgbox 列出 Outlook 多層資料夾整個樹狀結構目錄,這個 ShowMailNoteFolderTree() 副程式執行的時候,會把樹狀結構裡的一層一層的資料夾名稱組成在strFolderTre 這個字串變數裡,最後再把它 show 出來。
為了示範如何利用.DefaultMessageClass這個屬性,我刻意把程式寫成只列出"郵件與通知" 類別的資料夾,也就是篩選.DefaultMessageClass屬性為"IPM.Note"的資料夾。(另一個原因是若把所有類別的資料夾都列出來可能太多,Msgbox的樹狀目錄超過螢幕高度就......)
怎麼知道 "IPM.Note" 是 "郵件與通知" 類別呢?也不難,我先寫了一個不篩選類別的版本,把每個資料夾的 .DefaultMessageClass 屬性值都列在資料夾名稱右邊,就知道啦! Sub ShowMailNoteFolderTree()
Dim myNameSpace As Outlook.NameSpace Dim subFolder As Outlook.MAPIFolder Dim strFolderTree As String Dim i, TotalSubs, tmpSubs As Integer Dim LastOne As Boolean Set myNameSpace = Application.GetNamespace("MAPI") TotalSubs = 0 計算 ("郵件與通知" 類別的) 子資料夾個數 For Each subFolder In myNameSpace.Folders If subFolder.DefaultMessageClass = "IPM.Note" Then "IPM.Note" 字串由實測而得 TotalSubs = TotalSubs + 1 End If Next subFolder LastOne = False i = 0 tmpSubs = 0 strFolderTree = "MAPI Root" & vbCrLf For Each subFolder In myNameSpace.Folders 對於 Outlook MAPI 所有資料夾 If subFolder.DefaultMessageClass = "IPM.Note" Then 篩選符合 ("郵件與通知" 類別) 條件者 i = i + 1 If i = TotalSubs Then LastOne = True 判斷是否為最後一個 ("郵件與通知" 類別) 子資料夾 tmpSubs = tmpSubs + AddSubTree(strFolderTree, subFolder, "", LastOne) 列出此資料夾的子樹 End If End If
Next subFolder MsgBox strFolderTree & vbCrLf & "總計列出 " & TotalSubs + tmpSubs & " 個資料夾" End Sub 在 ShowMailNoteFolderTree() 裡將多次叫用 AddSubTree() 來為 Outlook 第一層各資料夾建立它的子樹狀結構目錄。AddSubTree() 是一個用 "遞迴呼叫 (Recursion Call)" 的做法寫的函數,簡單的說,當它把指定的資料夾之名稱 (.Name) 加到目錄樹字串裡之後,如果這個指定的資料夾有子樹的話,它就會叫用 "它自己" 來處理子樹。
我把AddSubTree()的參數和傳回值意義寫在底下的程式碼註解裡,AddSubTree()的傳回值則是累加的,每一個被叫用的AddSubTree()都會傳回它的子樹大小(含有的資料夾數),所以,最後可以算出整個樹狀結構目錄的資料夾總數。
此外,閱讀的時候請特別注意 trTree是 "ByRef"(傳址的)!藉由傳址的方法,從 ShowMailNoteFolderTree()裡的strFolderTree 這個字串變數"本身"(不是它的"變數值" 喔!) 會被傳給被叫用的AddSubTree(),一路傳遞下去,所以字串會愈接愈長,直到 ShowMailNoteFolderTree()裡最後執行到Msgbox把它show出來為止。
Function AddSubTree(ByRef strTree As String, thisFolder As Outlook.MAPIFolder, _
strPrefix As String, isLast As Boolean) As Integer 參數:strTree = 資料夾樹字串,thisFolder = 這個資料夾要被列出名稱和其子資料夾樹 strPrefix = 在此資料夾名稱前面要加的樹枝字串 isLast = 此資料夾本身是否為其父資料夾裡的最後一個 ("郵件與通知" 類別) 子資料夾 傳回值:此資料夾之子資料夾樹內的資料夾總數 Dim myNameSpace As Outlook.NameSpace Dim subFolder As Outlook.MAPIFolder Dim i, TotalSubs, tmpSubs As Integer Dim LastOne As Boolean If isLast Then 若是最後一個子資料夾,則名稱前面加 "└" 分支,否則就加 "├" 分支 strTree = strTree & strPrefix & "└" & thisFolder.Name & vbCrLf Else strTree = strTree & strPrefix & "├" & thisFolder.Name & vbCrLf End If 此資料夾全部應有這麼多個子資料夾 TotalSubs = thisFolder.Folders.Count 但此題我只想列出 "郵件與通知" 類別的子資料夾 TotalSubs = 0 計算 ("郵件與通知" 類別的) 子資料夾個數 For Each subFolder In thisFolder.Folders If subFolder.DefaultMessageClass = "IPM.Note" Then "IPM.Note" 字串由實測而得 TotalSubs = TotalSubs + 1 End If Next subFolder If TotalSubs <> 0 Then 此資料夾若有 ("郵件與通知" 類別的) 子資料夾 LastOne = False tmpSubs = 0 i = 0 For Each subFolder In thisFolder.Folders , 就把它所有的子資料夾樹列出來 If subFolder.DefaultMessageClass = "IPM.Note" Then 篩選符合條件者 i = i + 1 If i = TotalSubs Then LastOne = True 判斷是否為最後一個子資料夾 If isLast Then 若此資料夾本身是其父資料夾的最後一個 ("郵件與通知" 類別的) 子資料夾,就在其子資料夾名稱前面加一個全型的空白字元 tmpSubs = tmpSubs + AddSubTree(strTree, subFolder, strPrefix & " ", LastOne) Else 否則,就在其子資料夾名稱前面加一個 "│" 樹枝 tmpSubs = tmpSubs + AddSubTree(strTree, subFolder, strPrefix & "│", LastOne) End If End If Next subFolder End If AddSubTree = TotalSubs + tmpSubs 傳回子資料夾樹內的 ("郵件與通知" 類別的) 資料夾總數 End Function ※ 以上程式碼裡因有使用 "│"、 " " 、"└"、"├" 等 BIG5 碼特殊字元,所以需在 BIG5 中文內碼的環境執行才能正常顯示。
※ 關於如何在 Outlook 裡執行巨集,請看這篇文章: 在 Outlook 裡使用巨集 ※ 如需本文提及之各物件、集合、型別、屬性等等的詳細資料,請查 Outlook VBA 的 Help,或 Office 2003 VBA語言參考手冊 |
|
( 興趣嗜好|電腦3C ) |