1.學學基礎的VB語法
https://www.yiibai.com/vba/vba_programming_charts.html
2.找一個樣例看看
VBA編程實現自動回復郵件
https://blog.csdn.net/tclxspy/article/details/50714783
3.改造樣例
取msdn上看看開發文檔
https://docs.microsoft.com/zh-cn/office/vba/outlook/concepts/getting-started/using-macros-to-customize-outlook
4.關鍵點
實現方式:COM,VBA
采用簡單的方式實現VBA。
5.坑
(1)導入庫
VBA編程提示編譯錯誤用戶定義類型未定義:需要找到自己引用的庫導入
Q:如何在VBA中添加對InternetExplorer對象的引用?
A:方法1:前期綁定:Alt+F11>VBE編輯環境>菜單欄>工具>引用>Microsoft Internet Controls
ie庫(internet controls),mshtml(microsoft html Object library), microsoft xml library, 正則庫,microsoft activeX庫,
(2)activex 部件不能創建對象
Set ie =CreateObject("InternetExplorer.Application")
ie.visible=true
ie.navigate "http://www.baidu.com"
提示: "運行時錯誤'429': ActiveX 部件不能創建對象 "... 或: "Run-time error '429' ActiveX componnent can't create object"...
a.設置工具--引用 microsoft ActiveX data objects 2.0 library
b.Internet選項 - 安全設置里,恢復為默認級別。
Internet選項 - 安全設置里面,可以自定義級別,只要確保ActiveX控件是啟用狀態。
(3)
6.開發技巧:
(1) alt + F11打開開發ide
(2) ctrl + g 打開立即窗口,調試信息輸出
(3) 視圖——>監視窗口,打開變量監控窗口
(4)單步調試 F8
7.VBA IE對象的操作方法
http://www.360doc.com/content/18/0223/17/52075843_731761102.shtml
https://blog.csdn.net/kendyhj9999/article/details/52267469?locationNum=4&fps=1
8.VBA面向對象
http://mini.eastday.com/mobile/170603152045489.html
demo1
'郵件自動轉發處理子程序
'功能:根據發件人過濾,讀取未讀郵件,轉發郵件
'
'
Sub AutoForward(rcvMail As Outlook.MailItem)
'定義郵件轉發項目
Dim myAutoForwardMailItem As Outlook.MailItem
Dim rcvhtmlBody As String
Dim rcvBody As String
Dim mto As String
Dim ie, dmt, bd
'定義郵件體
Dim myAutoForwardHTMLBody As String
'創建郵件體
myForwardHTMLBody = CreateHTMLBody(2)
If (rcvMail.UnRead) And (rcvMail.SenderEmailAddress = "942387T841U@qq.com") Or (rcvMail.SenderEmailAddress = "rdmod01@163.com") Or (rcvMail.SenderEmailAddress = "ju.li@163.com") Then
'將郵件設為已讀
rcvMail.UnRead = False
'設置轉發器
Set myAutoForwardMailItem = rcvMail.ReplyAll
'設置收件人
myAutoForwardMailItem.Recipients.Add "xx@qq.com"
myAutoForwardMailItem.Recipients.Add "yy@qq.com"
rcvhtmlBody = rcvMail.HTMLBody
rcvBody = rcvMail.Body
mto = rcvMail.To
Debug.Print ("htmlBody string: " & rcvhtmlBody)
Debug.Print ("Body string: " & rcvBody)
Debug.Print ("Recipients: " & mto)
'處理郵件內容
Set ie = CreateObject("InternetExplorer.Application")
'設置郵件體格式為outlook html格式
myAutoForwardMailItem.BodyFormat = olFormatHTML
'將原始郵件與新郵件連起來
myAutoForwardMailItem.HTMLBody = myForwardHTMLBody & myAutoForwardMailItem.HTMLBody
'Displays a new Inspector object for the item.
'myAutoForwardMailItem.Display
'發送郵件
'Sends the e-mail message.
myAutoForwardMailItem.Send
'原保存郵件
'Saves the Microsoft Outlook item to the current folder or, if this is a new item, to the Outlook default folder for the item type.
rcvMail.Save
End If
'清空對象
Set rcvMail = Nothing
Set myAutoReplyMailItem = Nothing
End Sub
Sub AutoForward1()
Debug.Print ("xxx:" & RemoveHTML)
End Sub
Public Function CreateHTMLBody(id As Integer) As String
'Creates a new e-mail item and modifies its properties
Dim objHTMLBody As String
'可以設置多個模板
If id = 1 Then
objHTMLBody = _
"<font face = 微軟雅黑 size = 3>" & _
"感謝你的來信。我是<font color=red>機器人小星</font>,郵件我已代為閱讀。" & _
"<br/> <br/> " & _
"來自小星的智能轉發</font>"
ElseIf id = 2 Then
objHTMLBody = _
"<table style = border-collapse:collapse <tbody>" & _
"<tr><td style = border:1px solid #B0B0B0 colspan= 2>版本</td></tr>" & _
"<tr><td style= border:1px solid #B0B0B0 >APP版本</td></tr>" & _
"<tr><td style = border:1px solid #B0B0B0>SDK版本</td></tr>" & _
"</tbody></table>" & _
"" & _
"<br/> <br/> " & _
"來自小星的智能回復</font>"
End If
CreateHTMLBody = objHTMLBody
End Function
Sub test()
Dim str As String
Dim result As String
str = _
"<table style = border-collapse:collapse <tbody>" & _
"<tr><td style = border:1px solid #B0B0B0 colspan= 2>版本</td></tr>" & _
"<tr><td style= border:1px solid #B0B0B0 >APP版本</td></tr>" & _
"<tr><td style = border:1px solid #B0B0B0>SDK版本</td></tr>" & _
"</tbody></table>" & _
"" & _
"<br/> <br/> " & _
"來自小星的智能回復</font>"
result = RemoveHTML(str)
Debug.Print (result)
End Sub
'移除html標簽
Public Function RemoveHTML(strText As String)
Dim nPos1
Dim nPos2
Debug.Print ("Body string: ")
nPos1 = InStr(strText, "<")
Do While nPos1 > 0
nPos2 = InStr(nPos1 + 1, strText, ">")
If nPos2 > 0 Then
strText = Left(strText, nPos1 - 1) & Mid(strText, nPos2 + 1)
Else
Exit Do
End If
nPos1 = InStr(strText, "<")
Loop
RemoveHTML = strText
End Function
demo2
Sub searchWebViaIE()
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Dim anchors As MSHTML.IHTMLElementCollection
Dim anchor As MSHTML.HTMLAnchorElement
Dim prodSpec As MSHTML.HTMLAnchorElement
Dim tableCells As MSHTML.IHTMLElementCollection
Dim materialValueElement As MSHTML.HTMLTableCell
Dim tableCell As MSHTML.HTMLTableCell
Set ie = New SHDocVw.InternetExplorer
'Set ie = CreateObject("InternetExplorer.Application")
With ie
.navigate "http://www.baidu.com"
.Visible = True
Do While .readyState <> READYSTATE_COMPLETE Or .Busy = True
DoEvents
Loop
Set doc = .document
Set anchors = doc.getElementsByTagName("a")
For Each anchor In anchors
If InStr(anchor.innerHTML, "Product Specificatie") <> 0 Then
anchor.Click
Exit For
End If
Next anchor
Do While .readyState <> READYSTATE_COMPLETE Or .Busy = True
DoEvents
Loop
End With
For Each anchor In anchors
If InStr(anchor.innerHTML, "Product Specificatie") <> 0 Then
Set prodSpec = anchor
End If
Next anchor
Set tableCells = doc.getElementById("list-table").getElementsByTagName("td")
If Not tableCells Is Nothing Then
For Each tableCell In tableCells
If tableCell.innerHTML = "Materiaal" Then
Set materialValueElement = tableCell.NextSibling
End If
Next tableCell
End If
MsgBox materialValueElement.innerHTML
End Sub
demo3
'郵件自動轉發處理子程序
'功能:根據發件人過濾,讀取未讀郵件,轉發郵件
'
'
Sub AutoForward(rcvMail As Outlook.mailitem)
'定義郵件轉發項目
Dim myAutoForwardMailItem As Outlook.mailitem
Dim rcvhtmlBody As String
Dim rcvBody As String
Dim mto As String
'Dim ie, dmt, bd
Dim sender As String
'定義郵件體
Dim myAutoForwardHTMLBody As String
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
'創建郵件體
myForwardHTMLBody = CreateHTMLBody(2)
If (rcvMail.UnRead) And (rcvMail.SenderEmailAddress = "94s841@qq.com") Or (rcvMail.SenderEmailAddress = "rdmod01@163.com") Or (rcvMail.SenderEmailAddress = "ju.li@163.com") Then
'將郵件設為已讀
rcvMail.UnRead = False
'設置轉發器
Set myAutoForwardMailItem = rcvMail.ReplyAll
'rcvMail.Attachments.item(1).SaveAsFile ("D:\")
'設置收件人
myAutoForwardMailItem.Recipients.Add "2s3016@qq.com"
myAutoForwardMailItem.Recipients.Add "129s615@qq.com"
rcvhtmlBody = rcvMail.HTMLBody
rcvBody = rcvMail.body
mto = rcvMail.To
Debug.Print ("htmlBody string: " & rcvhtmlBody)
Debug.Print ("Body string: " & rcvBody)
Debug.Print ("Recipients: " & mto)
'處理郵件內容
'Set ie = CreateObject("InternetExplorer.Application")
'保存附件
saveAttachments rcvMail
'解析郵件主體
resolveAttach
Set ie = New SHDocVw.InternetExplorer
'Set doc = .document
'設置郵件體格式為outlook html格式
myAutoForwardMailItem.BodyFormat = olFormatHTML
'將原始郵件與新郵件連起來
myAutoForwardMailItem.HTMLBody = myForwardHTMLBody & myAutoForwardMailItem.HTMLBody
'Displays a new Inspector object for the item.
'myAutoForwardMailItem.Display
'發送郵件
'Sends the e-mail message.
myAutoForwardMailItem.Send
'原保存郵件
'Saves the Microsoft Outlook item to the current folder or, if this is a new item, to the Outlook default folder for the item type.
rcvMail.Save
End If
'清空對象
Set rcvMail = Nothing
Set myAutoReplyMailItem = Nothing
End Sub
Sub saveAttachments(mailitem As Outlook.mailitem)
Dim olAtt As Attachment
Dim count: count = mailitem.attachments.count
Dim attachments: attachments = mailitem.attachments
Dim i: i = 0
While i < count
i = i + 1
'附件索引從1開始
Set olAtt = attachments(i)
olAtt.SaveAsFile "D:\firefly\" & olAtt.FileName
Wend
End Sub
Sub resolveAttach()
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Dim body As MSHTML.HTMLBody
Set ie = New SHDocVw.InternetExplorer
ie.Visible = False
ie.navigate "D:\firefly\test.html"
Do Until ie.readyState = 4 '檢查網頁是否加載完畢
DoEvents '沒有加載完畢就將權限還給系統
Loop
Set doc = ie.document
Set body = doc.body
body.
End Sub
Public Function CreateHTMLBody(id As Integer) As String
'Creates a new e-mail item and modifies its properties
Dim objHTMLBody As String
'可以設置多個模板
If id = 1 Then
objHTMLBody = _
"<font face = 微軟雅黑 size = 3>" & _
"感謝你的來信。我是<font color=red>機器人小星</font>,郵件我已代為閱讀。" & _
"<br/> <br/> " & _
"來自小星的智能轉發</font>"
ElseIf id = 2 Then
objHTMLBody = _
"<table style = border-collapse:collapse <tbody>" & _
"<tr><td style = border:1px solid #B0B0B0 colspan= 2>版本</td></tr>" & _
"<tr><td style= border:1px solid #B0B0B0 >APP版本</td></tr>" & _
"<tr><td style = border:1px solid #B0B0B0>SDK版本</td></tr>" & _
"</tbody></table>" & _
"" & _
"<br/> <br/> " & _
"來自小星的智能回復</font>"
End If
CreateHTMLBody = objHTMLBody
End Function
Sub test()
Dim str As String
Dim result As String
str = _
"<table style = border-collapse:collapse <tbody>" & _
"<tr><td style = border:1px solid #B0B0B0 colspan= 2>版本</td></tr>" & _
"<tr><td style= border:1px solid #B0B0B0 >APP版本</td></tr>" & _
"<tr><td style = border:1px solid #B0B0B0>SDK版本</td></tr>" & _
"</tbody></table>" & _
"" & _
"<br/> <br/> " & _
"來自小星的智能回復</font>"
result = RemoveHTML(str)
Debug.Print (result)
End Sub
'移除html標簽
Public Function RemoveHTML(strText As String)
Dim nPos1
Dim nPos2
Debug.Print ("Body string: ")
nPos1 = InStr(strText, "<")
Do While nPos1 > 0
nPos2 = InStr(nPos1 + 1, strText, ">")
If nPos2 > 0 Then
strText = Left(strText, nPos1 - 1) & Mid(strText, nPos2 + 1)
Else
Exit Do
End If
nPos1 = InStr(strText, "<")
Loop
RemoveHTML = strText
End Function
'''
'需求描述
'公司里面每天都會有很多郵件,三分之一都是不需要看的,Outlook的過濾功能不錯,都可以處理掉。還有些郵件,根據正文或者附件做一下處理自動轉發出去就行了。於是上網搜集了一些資料,寫個了小程序,共享一下,以后可以參考,也希望對大家有點用處。
'實現
'廢話少說,直接上代碼吧。打開Outlook,按Alt+F11打開代碼編輯器,輸入下面的代碼。可能有些兄弟不知道怎么入手,后面會放幾個鏈接做參考。
'
'編輯完保存,在”開始->規則->創建規則”中添加一個過濾規則,在”如何處理該郵件”中選擇運行腳本,並選擇這個腳本。
Sub AutoResponseReceipt(item As mailitem)
Debug.Print ("receive an email")
Dim id As String
Dim SubjectString As String
Dim sender As String
Dim email As Outlook.mailitem
On Error GoTo Err
id = item.EntryID ' 先獲取郵件的ID
Set email = Application.Session.GetItemFromID(id)
SubjectString = email.Subject ' 郵件主題
sender = email.SenderEmailAddress ' 郵件的發送人地址
Debug.Print ("new email arrivaved: subject is " & SubjectString & " sender is " & sender)
Debug.Print ("new email arrivaved: subject is " & SubjectString & " recvs is " & email.Recipients)
' 校驗主題,這里是對主題做過濾,不合適的直接返回不處理
Dim index As Integer
index = InStr(SubjectString, "小票")
If 0 = index Then
index = InStr(SubjectString, "receipt")
If 0 = index Then
Return
End If
End If
' 下面這一段是我自己的一些處理邏輯,調用程序處理附件,
' 然后將程序處理后的結果當做附件轉發給另一個人
' 獲取附件並執行小票生成程序
Dim PathPrefix As String
PathPrefix = "E:\document\receipt_tool\"
Dim InputFileList As New Collection ' 這個列表存放收到的附件
Dim OutputFileList As New Collection ' 存放程序生成的結果
Dim AttachFile As Attachment ' 附件
For Each AttachFile In email.attachments ' email.attachments是所有附件
Debug.Print ("attachment: " & AttachFile.FileName)
Dim InputFile As String
Dim OutputFile As String
InputFile = PathPrefix & AttachFile.FileName
OutputFile = PathPrefix & AttachFile.FileName & ".docx"
Debug.Print ("input file is " & InputFile)
Debug.Print ("output file is " & OutputFile)
AttachFile.SaveAsFile (InputFile) ' 保存附件
Dim cmd As String
cmd = """" & PathPrefix & "receipt.exe" & """" & " " & InputFile & " " & OutputFile
Debug.Print ("command string: " & cmd)
Shell (cmd) ' 執行腳本,生成結果
InputFileList.Add (InputFile)
OutputFileList.Add (OutputFile)
'Kill (InputFile) ' 這里刪除的話總會把生成的文件同時刪掉
Next
If OutputFileList.count = 0 Then
Debug.Print ("no attachment")
End If
' 轉發郵件
Dim OutMail As Object
Set OutMail = Outlook.Application.CreateItem(olMailItem)
With OutMail
.To = "hnwyllmm@126.com" ' 要轉發郵件的收件人地址
.Subject = "打印:" & email.Subject ' 轉發郵件的主題
.body = "幫忙打印小票,謝謝!" & Chr(10) & email.SenderEmailAddress & Chr(10) & email.SenderName ' 轉發郵件的正文
End With
Dim SendAttach As String ' 將程序生成的結果添加到附件中
For i = 1 To OutputFileList.count
' MsgBox (SendAttach)
SendAttach = OutputFileList(i)
OutMail.attachments.Add (SendAttach)
Next
MsgBox ("send")
OutMail.Send ' 發送郵件
OutMail.Delete ' 刪除郵件,沒用了
Err:
' 刪除生成的文件
For i = 1 To OutputFileList.count
Kill (OutputFileList(i))
Next
For i = 1 To InputFileList.count
Kill (InputFileList(i))
Next
email.Delete ' 刪除收到的郵件
' 下面幾個是釋放對象,其實沒有也無所謂
Set InputFileList = Nothing
Set OutputFileList = Nothing
Set OutMail = Nothing
End Sub
Sub Command1_Click7()
Dim str As String
Dim li, cd
Dim c_name As String
'遍歷元素<li>
For Each li In Dom.document.getElementsByTagName("li")
'用判斷忽略掉列首名稱的<li>行
If li.classname = "lst_row" Then
'遍歷<li>下的節點
For Each cd In li.ChildNodes
'判斷是否為元素節點
If cd.NodeType <> 3 Then
If cd.classname = "col_2" Then
'如果是第2列的<span>,那么再用firstChild取出第一個元素節點<a>
str = str & cd.FirstChild.href & " "
Else
'其他列直接輸出文本
str = str & cd.innertext & " "
End If
End If
Next
str = str & vbCrLf
End If
Next
Print str
End Sub
Sub ParseMaterial()
Dim Cell As Integer
Dim ItemNbr As String
Dim AElement As Object
Dim AElements As IHTMLElementCollection
Dim ie As MSXML2.XMLHTTP60
Set ie = New MSXML2.XMLHTTP60
Dim HTMLDoc As MSHTML.HTMLDocument
Dim HTMLBody As MSHTML.HTMLBody
Set HTMLDoc = New MSHTML.HTMLDocument
Set HTMLBody = HTMLDoc.body
For Cell = 1 To 5 'I iterate through the file row by row
ItemNbr = Cells(Cell, 3).Value 'ItemNbr isin the 3rd Column of my spreadsheet
ie.Open "GET", "http://www.example.com/?item=" & ItemNbr, False
ie.Send
While ie.readyState <> 4
DoEvents
Wend
HTMLBody.innerHTML = ie.responseText
Set AElements = HTMLDoc.getElementById("list-table").getElementsByTagName("tr")
For Each AElement In AElements
If AElement.Title = "Material" Then
Cells(Cell, 14) = AElement.NextNode.Value 'I write the material in the 14th column
End If
Next AElement
Application.Wait (Now + TimeValue("0:00:2"))
Next Cell
End Sub
<html>
<body>
<table width="400" border="1">
<tr>
<th align="left">消費項目....</th>
<th align="right">一月</th>
<th align="right">二月</th>
</tr>
<tr>
<td align="left">衣服</td>
<td align="right">241.10</td>
<td align="right">50.20</td>
</tr>
<tr>
<td align="left">化妝品</td>
<td align="right">30.00</td>
<td align="right">44.45</td>
</tr>
<tr>
<td align="left">食物</td>
<td align="right">730.40</td>
<td align="right">650.00</td>
</tr>
<tr>
<th align="left">總計</th>
<th align="right">1001.50</th>
<th align="right">744.65</th>
</tr>
</table>
<p>每個表格由 table 標簽開始。</p>
<p>每個表格行由 tr 標簽開始。</p>
<p>每個表格數據由 td 標簽開始。</p>
<h4>一列:</h4>
<table border="1">
<tr>
<td>100</td>
</tr>
</table>
<h4>一行三列:</h4>
<table border="1">
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
</table>
<h4>兩行三列:</h4>
<table border="1">
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>400</td>
<td>500</td>
<td>600</td>
</tr>
</table>
<table border="6">
<caption>我的標題</caption>
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>400</td>
<td>500</td>
<td>600</td>
</tr>
</table>
<h4>Disc 項目符號列表:</h4>
<ul type="disc">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ul>
<h4>Circle 項目符號列表:</h4>
<ul type="circle">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ul>
<h4>Square 項目符號列表:</h4>
<ul type="square">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ul>
<h4>數字列表:</h4>
<ol>
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ol>
<h4>字母列表:</h4>
<ol type="A">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ol>
<h4>小寫字母列表:</h4>
<ol type="a">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ol>
<h4>羅馬字母列表:</h4>
<ol type="I">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ol>
<h4>小寫羅馬字母列表:</h4>
<ol type="i">
<li>蘋果</li>
<li>香蕉</li>
<li>檸檬</li>
<li>桔子</li>
</ol>
<h4>一個嵌套列表:</h4>
<ul>
<li>咖啡</li>
<li>茶
<ul>
<li>紅茶</li>
<li>綠茶</li>
</ul>
</li>
<li>牛奶</li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<div>
<ul class="lstbox">
<li class="lst_head"><span class="col_1">姓名</span><span class="col_2">郵箱</span><span class="col_3">生日</span></li>
<li class="lst_row"><span class="col_1">張三</span><span class="col_2"><a href="mailto:zhangsan@web.com" class="email">zhangsan</a></span><span class="col_3">80-5-1</span></li>
<li class="lst_row"><span class="col_1">李四</span><span class="col_2"><a href="mailto:lisi@web.com" class="email">lisi</a></span><span class="col_3">85-5-1</span></li>
<li class="lst_row"><span class="col_1">王五</span><span class="col_2"><a href="mailto:wangwu@web.com" class="email">wangwu</a></span><span class="col_3">90-5-1</span></li>
<li class="lst_row"><span class="col_1">趙六</span><span class="col_2"><a href="mailto:zhaoliu@web.com" class="email">zhaoliu</a></span><span class="col_3">95-5-1</span></li>
</ul>
</div>
</body>
</html>
將顯示名稱映射到電子郵件地址
https://docs.microsoft.com/zh-cn/office/vba/outlook/concepts/address-book/map-a-display-name-to-an-e-mail-address
獲取收件人的電子郵件地址
https://docs.microsoft.com/zh-cn/office/vba/outlook/concepts/address-book/obtain-the-e-mail-address-of-a-recipient
中文
https://msdn.microsoft.com/zh-cn/library/ee814736.aspx
http://www.snb-vba.eu/VBA_Outlook_external_en.html#L_3.2.1
