[英]Excel VBA: assistance editing an outlook email parser in excel
I've been trying to create an email parser that has excel go through my outlook emails in a specific, designated folder. 我一直在尝试创建一个具有excel的电子邮件解析器,该解析器在特定的指定文件夹中浏览我的Outlook电子邮件。 The code below works great, i modified it from another forum, except for one issue: in the emails i'm trying to parse, the bottom section can contain multiple items.
下面的代码很好用,我从另一个论坛修改了它,除了一个问题:在我要解析的电子邮件中,底部可能包含多个项目。 I basically need this to repeat these steps for every instance of the word "item," but with the next item and its associated sku, qty, and cost.
我基本上需要这样做,以便对单词“ item”的每个实例重复这些步骤,但要包含下一个项目及其相关的sku,qty和cost。
So, when it's done with an email and moves on to the next, it should look like this in excel: 因此,当处理完电子邮件并转到下一封电子邮件时,它在excel中应如下所示:
fax, date, cust1, cust address1, item1, sku1, qty1, cost1 传真,日期,客户1,客户地址1,项目1,SKU1,数量1,成本1
fax, date, cust1, cust address1, item2, sku2, qty2, cost2 传真,日期,客户1,客户地址1,项目2,sku2,数量2,成本2
fax, date, cust2, cust address2, item1, sku1, qty1, cost1 传真,日期,客户2,客户地址2,项目1,sku1,数量1,成本1
Is there any way to do this? 有什么办法吗?
Below is my current code, but it just shows the first instance of the product, sku, qty, and cost, and then moves on to the next email. 下面是我当前的代码,但仅显示了产品的第一个实例,sku,数量和成本,然后继续处理下一封电子邮件。
Dim msgText As String
Dim msgLine() As String
Dim messageArray() As String
i = 0
For Each myOlMailItem In myOlFolder.Items
i = i + 1 ' first parsed message ends up on worksheet one row below headings
msgText = myOlMailItem.Body
messageArray = Split(msgText, vbCrLf) ' split into lines
For j = 0 To UBound(messageArray)
msgLine = Split(messageArray(j) & ":", ":") ' split up line ( add ':' so that blank lines do not error out)
Select Case Left(msgLine(0), 3)
Case "FAX"
anchor.Offset(i, 0).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 4)
Case "DATE"
anchor.Offset(i, 1).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 6)
Case "CUSTOM"
anchor.Offset(i, 2).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 6)
Case "CUSTOM"
anchor.Offset(i, 3).Value = messageArray(j + 1) + messageArray(j + 2) + messageArray(j + 3)
End Select
Select Case Left(msgLine(0), 4)
Case "ITEM"
anchor.Offset(i, 4).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 3)
Case "SKU"
anchor.Offset(i, 5).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 8)
Case "QTY"
anchor.Offset(i, 6).Value = msgLine(1)
End Select
Select Case Left(msgLine(0), 4)
Case "COST"
anchor.Offset(i, 7).Value = msgLine(1)
End Select
Next
anchor.Offset(i, -1).Value = myOlMailItem.SenderName
' add row number on left of "Priority" column (make sure that "anchor" is not in first worksheet column)
Next
End Sub
The emails look like the below. 电子邮件如下所示。 They can have variable amounts of items ordered.
他们可以订购数量不定的物品。 The below template shows how 3 different items would appear.
以下模板显示了3种不同的项目。
DATE : 12/01/2018
------------------------------------------------------------
CUSTOMER : CUSTOMER NAME
: ADDRESS
: ADDRESS
: ADDRESS
PHONE : PHONE
FAX : FAX
------------------------------------------------------------
DELIVER TO : DELIVER TO CUSTOMER
: ADDRESS
: ADDRESS
: ADDRESS
------------------------------------------------------------
ITEM NAME : ITEM NAME
SKU : SKU
QTY : QTY #
COST : COST $
------------------------------------------------------------
ITEM NAME : ITEM NAME
SKU : SKU
QTY : QTY #
COST : COST $
------------------------------------------------------------
ITEM NAME : ITEM NAME
SKU : SKU
QTY : QTY #
COST : COST $
------------------------------------------------------------
This should get you close: 这应该使您接近:
Dim keyValuePairs() As String ' Fields extracted from the e-mail
Dim messageLines() As String ' Individual Lines in the e-mail
Dim itemList() As String ' List of Item information in a single e-mail
' (0, n) = Item Name of Item n
' (1, n) = SKU of Item n
' (2, n) = Quantity of Item n
' (3, n) = Cost of Item n
Dim currentItem As Integer ' Index for looping through customer item list
Dim customerName As String ' Customer Name
Dim customerAddress As String ' Customer Address
Dim customerPhone As String ' Customer Phone Number - Currently Ignored
Dim customerFax As String ' Customer Fax Number
Dim deliveryName As String ' Delivery Customer Name - Currently Ignored
Dim deliveryAddress As String ' Delivery Address - Currently Ignored
Dim messageLine As Integer ' Index for walking through message lines
Dim orderDate As String ' Date of Order
Dim parseState As String ' Manages which address is being parsed
Dim targetExcelRow As Integer ' Excel row on which to place data
Dim itemCount As Integer ' Number of items in a single e-mail
Dim itemValue As String ' Trimmed value
targetExcelRow = 1 ' Start placing items on the first row below headings
' Loop through e-mails
For Each myOlMailItem In myOlFolder.Items
' Set up for a New Message
messageLines = Split(myOlMailItem.Body, vbCrLf) ' Split the message body into lines
itemCount = -1 ' Reset the item count
ReDim itemList(3, 0) ' Reset the item list
customerName = "" ' Reset all static values
customerAddress = ""
customerFax = ""
customerPhone = ""
orderDate = ""
deliveryName = ""
deliveryAddress = ""
' Loop through the lines in the e-mail
For messageLine = 0 To UBound(messageLines)
' Array is expected to have only two values per line.
' Position 0 is the Key. Position 1 is the Value.
keyValuePairs = Split(messageLines(messageLine), ":")
If UBound(keyValuePairs) > 0 Then ' This ignores blank lines and dividers
itemValue = Trim$(keyValuePairs(1))
Select Case Trim$(keyValuePairs(0))
Case "DATE"
orderDate = itemValue
parseState = ""
Case "CUSTOMER"
customerName = itemValue
parseState = "CUSTADDR"
Case "FAX"
customerFax = itemValue
Case "DELIVER TO"
deliveryName = itemValue
parseState = "DELIVADDR"
Case "ITEM NAME"
itemCount = itemCount + 1
ReDim Preserve itemList(3, itemCount)
itemList(0, itemCount) = itemValue
Case "SKU"
itemList(1, itemCount) = itemValue
Case "QTY"
itemList(2, itemCount) = itemValue
Case "COST"
itemList(3, itemCount) = itemValue
Case "PHONE"
customerPhone = itemValue
Case "" ' Handle blank field names
Select Case parseState
Case "CUSTADDR"
customerAddress = customerAddress + itemValue
Case "DELIVADDR"
deliveryAddress = deliveryAddress + itemValue
Case Else ' Error: Unhandled State
'Debug.Print "Unhandled blank field encountered at message line " & Trim$(CStr(j + 1)) & "."
Err.Raise Number:=vbObjectError, _
source:="E-Mail Parse Function", _
Description:="Unhandled blank field encountered at message line " & Trim$(CStr(j + 1)) & "."
End Select
Case Else
'Debug.Print "Unhandled keyword encountered at message line " & Trim$(CStr(j + 1)) & "."
Err.Raise Number:=vbObjectError, _
source:="E-Mail Parse Function", _
Description:="Unhandled keyword encountered at message line " & Trim$(CStr(j + 1)) & "."
End Select
End If
Next messageLine
' Now write the data to the Excel Sheet
For currentItem = 0 To itemCount
With anchor
.Offset(targetExcelRow, -1).Value = myOlMailItem.SenderName ' SenderName of Priority Column
.Offset(targetExcelRow, 0).Value = customerFax ' Fax Number
.Offset(targetExcelRow, 1).Value = orderDate ' Order Date
.Offset(targetExcelRow, 2).Value = customerName ' Customer Name
.Offset(targetExcelRow, 3).Value = customerAddress ' Customer Address
.Offset(targetExcelRow, 4).Value = itemList(0, currentItem) ' Item Name
.Offset(targetExcelRow, 5).Value = itemList(1, currentItem) ' SKU
.Offset(targetExcelRow, 6).Value = itemList(2, currentItem) ' Quantity
.Offset(targetExcelRow, 7).Value = itemList(3, currentItem) ' Cost
End With
targetExcelRow = targetExcelRow + 1
Next currentItem
Next myOlMailItem
If you prefer the system prints unhandled stuff to the immediate window, uncomment the Debug.Print
lines and comment the Err.Raise
lines. 如果您希望系统将未处理的内容打印到立即窗口,请取消注释
Debug.Print
行并注释Err.Raise
行。 I have tested this code for one loop using only the sample data you provided. 我仅使用您提供的示例数据对该代码进行了一个循环的测试。 It should work fine for any number of e-mails.
它适用于任何数量的电子邮件。
Notes: 笔记:
Select Case
statement for each case. Select Case
语句。 that was completely unnecessary. anchor
as a parameter. anchor
作为参数。 The code assumes that anchor has been defined and set. parseState
is used for managing cases when there are no field names on the line to identify the data. parseState
用于管理案例。 The Case ""
statement handles any of those cases. Case ""
语句处理任何这些情况。 The parseState
variable tells that case what to do with the blank line. parseState
变量告诉该情况空白行如何处理。 So, when you encounter the CUSTOMER
field, it sets the parseState
to "CUSTADDR" to let the blank field case know that it is parsing the customer address. CUSTOMER
字段时,它将parseState
设置为“ CUSTADDR”,以使空白字段的情况知道它正在解析客户地址。 Good Luck! 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.