大家好,我是太空鐵。
OUTLOOK是老鐵日常使用的郵件客戶端,平時收發郵件也比較多。如果所有郵件都混雜在一個郵件箱中,那么在翻查一些特定聯系人的往來郵件時會很麻煩,所以OUTLOOK專門提供了“規則”工具用來對收發郵件進行自動分類。
另外,如果OUTLOOK的規則工具不能滿足你的日常需求的話,那么還可以通過VBA來實現更加全方位的對郵件的操作,本文將以老鐵編寫的一個小項目為例,展示一下VBA編寫自動化郵件處理工具的方法,方便會使用VBA的朋友快速上手。
本文的提綱如下:
一、利用OUTLOOK規則工具對郵件進行自動分類
二、使用VBA實現郵件處理自動化
一、利用OUTLOOK規則工具對郵件進行自動分類
Outlook郵件很多的時候,默認是按照時間流來排序,實際工作中在回頭查找一些工作記錄的時候,往往記不清楚發生時間,但能記清楚往來郵件的相對人,所以按照發件人或收件人來分類更為適合。
規則工具設置的邏輯很明確,即是達成某種條件,執行某些動作。
1、建立發件人和收件人目錄
收件箱
上圖是收件箱的分類,可以看到,我的同事程咬金、李逵、李逍遙之類的,他們如果給我發郵件會自動進入這個郵箱,如果要翻查郵件,只要記得誰發的,直接進入他的文件夾就行了。
來看看如何設置吧:
在收件箱上點右鍵,選擇新建文件夾:
新建文件夾
然后,在彈出的小空格里填入文件夾的名字,可以用同事、事務的名字來命名:
流浪地球的電影還沒看
這樣,文件夾就建好了。
2、設定規則
點擊你想分類的郵件,然后再依次點擊:開始——規則——總是移動來自此人的郵件:
總是移動來自此人的郵件
在彈出的窗口選擇要移動到的文件夾:
點擊確定,就能把當前郵件和以后來自該發件地址的郵件,全部歸類到李逍遙這個目錄。
如果你有更高級的訴求,可以點擊創建規則:
點擊創建規則后,可以看到一個簡單的規則定制窗口:
創建規則
窗口上半部分可以定制包含的主題、收件人,下半部分是可選的執行操作,顯示通知、播放聲音、移至文件夾等,如果選擇右下角的高級選項按鈕,可以看到Outlook提供了豐富的可定制規則。
第一步是選擇條件,并且對條件進行編輯,這里面,發件人、主題、目的地址、標記等等都可以進行編輯:
第二步是選擇操作,可以移動郵件、刪除郵件、打印,轉寄等等:
第三步,可以選擇例外情況,意味著可以在某種情況下就不執行該操作,例外情況跟第一步的條件是一樣的:
第四步,即可以命名和保存規則,保存完后可以選擇立即執行規則處理目標郵件,這時候就可以溯及以往的郵件,不只是在新郵件上執行規則:
OK,有關使用規則工具對郵件進行分類的部分就介紹這么多,大家可以自己試驗一下,就知道這個功能的強大了。
下面來講解如何使用VBA實現郵件處理自動化。
二、使用VBA實現郵件處理自動化
VBA是Office內嵌的自動化工具,可以讓使用者更靈活的,以相對更底層的方式操作Office的各種功能,它是面向對象的,也是事件驅動的,并且以類似basic的語言方式來使用,方便使用者快速上手。
我將以一個實際的例子來介紹如何編寫一個Outlook的VBA程序。事情是這樣:
老婆在總公司做郵件分揀工作,公司的信息化很差,與下屬公司通過郵箱來傳遞文件,下屬公司經常會給總公司發一些PDF報表,老婆需要把這些郵件附件按照不同情況分派給不同的同事去處理,對附件進行重命名并做好登記記錄。
公司不愿意為這點事投建信息化系統,但由于郵件的量很大,老婆為這點事就要占幾個小時,因為上班時候還有工作,所以通常老婆下班就把這個工作帶回家,等孩子們都睡了再做,很是辛苦。
后來,老鐵就讓老婆跟下屬公司的人約定一個固定格式的郵件標題,把與分揀有關的內容都寫在標題里(比如訂單號,訂單類型等),然后編寫了一個VBA的程序,半自動化的處理郵件,將幾個小時的工作時間縮短到十分鐘以內。
這個程序需要實現的核心功能很簡單——識別郵件標題并進行歸類。程序主要對用戶點擊的郵件進行識別,把郵件標題上的信息摘取出來,附合一些分配人員的信息,將附件下載歸類再登記,基本上把原先拷貝復制的工作都簡化成點幾下鼠標了。
實現這個需求用了600來行代碼,
1、開始編寫代碼
在Outlook中編寫代碼非常容易,以前如果沒有寫過代碼可能需要先打開“開發工具選項卡”:依次點擊文件—選項—自定義功能區,勾選“開發工具”:
勾選開發工具后,開發工具選項卡會顯示在Outlook的界面上,點擊開發工具選項卡,再點擊Visual Basic,打開代碼編寫窗口:
在代碼編寫窗口中,左邊的工程窗口內,逐級展開project1,雙擊 ThisOutlokSession,可以打開代碼編寫區,我們的代碼就是在這個區域編寫的:
代碼主要分為兩個部分,一是通過用戶點擊郵件,程序提取所點擊郵件的相關信息,二是將相關信息顯示在一個窗體上,接受用戶修改和指定任務承擔人的操作,在用戶確認后進行登記和轉存附件。
2、核心功能1:點擊郵件并識別標題
代碼的核心功能之一是用戶點擊郵件,并對所點擊的郵件進行一系列的信息識別和提取。
Office的VBA程序都是事件驅動的,點擊郵件識別標題就需要在點擊郵件這個事件中進行編程,也就是說,點擊了郵件就去執行這段代碼。
點擊郵件的事件即是:Outlook.Explorer 對象的 SelectionChange()事件,顧名思義,這個事件是在選擇變化時觸發,觸發時,Outlook.Explorer 對象的 Selection 屬性存儲了當前選擇的郵件項目的所有信息。
所以,我們要做的就是建立這個事件,并在事件中處理Selection中的有關信息。
A.聲明和建立事件
聲明事件:
Public WithEvents myOlExp As Outlook.Explorer ‘全局變量
建立事件:
Private Sub myOlExp_SelectionChange()
End Sub
使用這個事件時,還有一點需要注意,SelectionChange在Outlook啟動期間會被觸發,選中郵件時又會觸發兩次,所以需要在事件之初做一些判斷,能夠對所需要的那次觸發做出處理,再添加以下代碼:
聲明觸發計數變量:
Public fireSelChange As Integer '全局變量,觸發計數器
在 myOlExp_SelectionChange() 事件中添加代碼:
Private Sub myOlExp_SelectionChange()
fireSelChange = fireSelChange + 1 '觸發計數
If appInit <> True Then '判定初始化是否完成
If fireSelChange Mod 2 = 0 Then '偶數次觸發才是選中所需郵件的那次觸發
'核心功能在此處實現
'……
fireSelChange = 2 '還原觸發計數為2
Else
End If
ElseIf appInit = True And fireSelChange = 2 Then appInit = False '應用處于啟動階段且已觸發兩次則設定為應用處于已啟動階段
End If
End Sub
B.獲取郵件標題
實現核心功能的思路主要是通過正則表達式對標題進行識別,將識別結果存儲在變量中,上文說到郵件內容都包含在Outlook.Explorer 對象的 Selection 屬性中,下面來看看具體如何獲取郵件標題。
Selection屬性是一個集合,可能包含多個項目,這個項目可能是郵件,也可能是聯系人、任務等其他Outlook支持的對象,在這里只考慮選擇一個郵件項目的情況,所以需要將Selection屬性強制轉換為 Outlook.MailItem 類型。
聲明局部變量:
Dim myOlSel As Outlook.Selection 'Selection 屬性
Dim strSubject As String '郵件標題
轉換類型:
Set myOlSel =?myOlExp.Selection '獲得Selection 屬性
If myOlSel.Count = 1 Then ‘判斷是否選擇了 1個項目
If myOlSel.Item(1).Class = OlObjectClass.olMail Then '判斷所選的項目是否為 郵件
Set oMail = myOlSel.Item(1) '將郵件賦值給局部變量
strSubject = oMail.Subject '提取郵件標題
End If
End If
提取出郵件標題后,還需要提取很多內容,都可以引用MailItem類的有關屬性,例如:
MailItem.Body '郵件正文
MailItem.ReceivedTime '郵件接收時間
MailItem.Attachments '郵件附件集合,可以使用For Each 遍歷附件集合,獲取附件文件名,另存附件等。
C.正則表達式和啟動窗體
VBA中使用正則表達式,可以從下面的代碼開始:
Set mRegExp = CreateObject("Vbscript.Regexp")
With mRegExp
?.Global = False? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'True表示匹配所有, False表示僅匹配第一個符合項
?.IgnoreCase = True? ? ? ? ? ? ? ? ? ? ? ? ? 'True表示不區分大小寫, False表示區分大小寫
?.Pattern = "(b|B|c|C){1}[0-9]{11}"? ?'匹配字符模式
Set mMatches = .Execute(strSubject)? ?'執行正則查找,返回所有匹配結果的集合,若未找到,則為空
‘其他內容
End With
經過一系列字符串提取工作,可以將字符串賦值給一個窗體,然后方便用戶在窗體上可視化的操作,這個窗體后面具體講解,這里只看一下如何賦值和顯示窗體:
With MailForm
.IDTB.Text = strID '給窗體中IDTB這個文本框(TB即TextBox)設置編號的字符串
.NameTB.Text = strName '給窗體中NameTB這個文本框設置名稱的字符串
'……其他代碼
.Show '顯示窗體
End With
3、核心功能2:在窗體中顯示有關數據,并接受用戶操作
由于發來的郵件千差萬別,很多郵件標題與約定的格式不能百分百一致,因此需要在提取信息后,給用戶(也就是我老婆)一個修改的機會,并請人工指定把任務分配給誰,所以需要一個窗體,顯示所有提取的信息,讓用戶指定任務承擔人,并在用戶確認這些信息后進行登記和存儲郵件附件的操作。
窗體設計如下圖:
按照業務需求,窗體上提取出的信息最后都會記錄到Excel文件中,同時也會合并到附件的文件名中。
使用VBA可以方便的在程序當中調用Excel或者Word等Office組件,并向文件中寫入內容,以下代碼可以添加到提交按鈕的點擊事件里:
Set xlapp = CreateObject("Excel.Application") '創建Excel對象。
Set wb = xlapp.workbooks.Open(recPathTB.Text) '打開記錄文件
Set sht = wb.Sheets(1) '獲取Excel表格的第一個sheet
i = sht.UsedRange.Rows.Count + 1 '計算單元格行數,i 即是定位到現有內容的最后一行。
sht.Cells(i, 1).Value = recvDateTB.Text
'將內容寫入單元格
......
wb.Close True '關閉文件
xlapp.Quit '清理實例
4、其他代碼
A.實現程序初始化
一般來說都要在Outlook啟動時,做一些初始化的工作,程序初始化的事件是 Application_Startup ,可以在這個程序中添加初始化代碼:
Private Sub Application_Startup()
Initialize_handler
End Sub
Initialize_handler 是一個自定義的函數,主要功能是在Outlook啟動之初添加一個類別標簽,并用這個標簽來標記已經處理的郵件。標簽一經添加,下次啟動就會存在不需要再添加,程序也會做出相應判斷,具體實現如下:
Sub Initialize_handler()
Dim objNameSpace As NameSpace
Dim objCategory As Category 'Outlook中郵件標簽對象,存儲了當前已有的標簽,例如緊急,普通等
Dim ifFinished As Boolean '標記是否已完成郵件處理的變量
Set myOlExp = Application.ActiveExplorer '代表Outlook窗口界面的對象
appInit = True '標志程序已經初始化
fireSelChange = 0 '初始化觸發selecttion_change 事件的次數。
'查看是否有已辦的標識
Set objNameSpace = Application.GetNamespace("MAPI")
ifFinished = False
For Each objCategory In objNameSpace.Categories
If objCategory.Name = "已辦" Then
ifFinished = True
Exit For
End If
Next
'如果沒有已辦標識則新增已辦標識
If ifFinished = False Then objNameSpace.Categories.Add ("已辦")
End Sub
B.獲取郵件附件相關信息
項目當中需要檢查郵件附件的文件名后綴是否為PDF,所以需要獲取郵件附件的相關信息:
郵件附件的對應的對象是 Attachment,存儲在MailItem.Attachments集合中,可以通過Foreach來遍歷郵件附件,另外為了保證能取到準確的文件擴展名,使用系統自帶Scripting.FileSystemObject對象的GetExtesion函數獲得,代碼如下:
Private Function FindAttachName() As String
Dim oAttachment As Attachment '聲明Attachment對象
Dim attachName As String '附件文件名字符串
Dim oFso As Object
Set oFso = CreateObject("Scripting.FileSystemObject") '設置FileSystemObject對象
FindAttachName = "" '設置返回值
For Each oAttachment In oMail.Attachments '遍歷附件,oMail是全局變量
If LCase(oFso.GetExtensionName(oAttachment.FileName)) = "pdf" Then '判斷附件文件名的擴展名是否為pdf
FindAttachName = oAttachment.FileName '設置返回值
Exit For
End If
Next
End Function
主要代碼就展示到這里,相關的Outlook運行流程、組件類庫等都有所涉及,算是拋磚引玉,源代碼可以到文章最后下載。
三、總結
Outlook的郵件分類是一個非常便捷的工具,如果你的工作依賴于郵件系統,那一定要嘗試進行分類,會節約很多時間,系統提供的規則工具已經可以進行初步的分類,日常工作足夠用了。
如果像老鐵一樣有特殊的要求,那么花幾天時間,照我的例子搞一個程序,也是可以考慮的,畢竟節約的時間都是自己的,而且總做一些機械重復的事情對心情也有不好的影響。
VBA編程對于有編程基礎的人也有一些門檻,門檻并不在于VBA本身,而在于一是需要了解VBA程序在Outlook中的運行流程,二是要了解其內建的類庫體系。我以前做過在其他代碼中操作Excel、Word的程序,寫Outlook的VBA程序也是第一次,不過好在相關的開發文檔,網上的各種例子也很多,所以開發還算順利。
就這樣,謝謝觀賞,老鐵從小學(94年)開始學編程,初高中寒暑假都會寫個程序,可惜后來上班卻沒怎么干過編程的工作,這是第一次寫編程的文章,請大家多多支持。