Need to extract from data from email body into Excel - vba

I'm a complete coding novice and I'm struggling with extracting the data out of an email bodies into an Excel 2010 sheet.
The format of the email is;
Form Response
First name John
Surname Smith
Email john.smith#test.com.au
Today's code word test1
I'v been trying my luck at various bits of VBA code I've found online however end up with Subscript out of Range errors when ever it gets to the body of the email;
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim olItem As Outlook.MailItem
Dim vText As Variant
Dim sText As String
Dim vItem As Variant
Dim i As Long
Dim rCount As Long
Dim bXStarted As Boolean
Const strPath As String = "c:\test\test1.xlsx" 'the path of the workbook
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("Sheet1")
'Process each selected record
For Each olItem In Application.ActiveExplorer.Selection
sText = olItem.Body
vText = Split(sText, Chr(13))
'Find the next empty line of the worksheet
rCount = xlSheet.UsedRange.Rows.Count
'Check each line of text in the message body
For i = UBound(vText) To 0 Step -1
rCount = rCount + 1
If InStr(1, vText(i), "First name ") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("A" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "Surname:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("B" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "Email:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("C" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "Today's code word ") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("D" & rCount) = Trim(vItem(1))
End If
Next i
xlWB.Save
Next olItem
xlWB.Close SaveChanges:=True
If bXStarted Then
xlApp.Quit
End If
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing
End Sub
Can anyone offer any help?
Thanks.

i think the Problem is caused by the use of the split-function.
Try this:
fist you need additionally
dim mystart as integer
dim myend as integer
and the delete everything with "vtext" and alter your code like this:
If InStr(1, sText, "First name ") > 0 Then
mystart = InStr(1, sText, "First name ") + 11
myend = InStr(mystart, sText, Chr(10)) - mystart - 1
vItem = mid(sText, mystart, myend)
xlSheet.Range("A" & rCount) = Trim(vItem)
End If
Hope this helps,
Max

What line of code throws an exception? Did you try to debug the code?
I'd recommend starting from the Getting Started with VBA in Outlook 2010 article. Also please remember that indexes start from 1, not 0.

Related

Extracting a word from Outlook Email Body while replying email with predefined Template

I have a working code which is extracting information from subject of initial email.
Sub InitialNotif()
Dim origEmail As MailItem
Dim replyEmail As MailItem
Dim INC1 As String 'For Serial Number
Dim INo As Integer 'For Serial Number
Dim LOC1 As String 'For Location
Dim LoC As Integer 'For Location
Dim SUMM As String 'For Summary
Dim Sum As Integer 'For Summary
Set origEmail = Application.ActiveWindow.Selection.item(1)
Set replyEmail = Application.CreateItemFromTemplate("H:\Documents\Test P1-.oft")
replyEmail.CC = ""
replyEmail.HtmlBody = replyEmail.HtmlBody & origEmail.Reply.HtmlBody
INC1 = origEmail.Subject
INo = InStr(1, INC1, "SR2")
LOC1 = origEmail.Subject
LoC= InStr(1, LOC1, "|") + 10
SUMM= origEmail.Subject
Sum= InStr(1, SUMM, "Summary") + 30
replyEmail.Subject = " <P1> - " & INC1
replyEmail.HtmlBody = Replace(replyEmail.HtmlBody, "INC1", INC1)
replyEmail.Display
End Sub
Now I would like to fetch information from body of the email. Below is the format of body of the email.
Serial Number: SR23443354
Location: Canada
Summary: Replacement request
I need above information to be replaced with my .otf Template. So when I run the script it should auto populate or replace required field.
Template Body:
Serial Number: INC1
Location: LOC
Summary: SUMM
When I tried replacing origEmail.Subject with origEmail.body its giving me entire email in scattered format.
Change ActiveWindow With ActiveExplorer
MSDN Split Function
MSDN Replace Function
MSDN InStr Function
Option Explicit
Sub InitialNotif()
Dim OrigEmail As MailItem
Dim ReplyEmail As MailItem
Dim vText As Variant
Dim vItem As Variant
Dim SerialNum As String
Dim Location As String
Dim Summary As Variant
Dim i As Long
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox ("No Item selected")
Exit Sub
End If
Set OrigEmail = Application.ActiveExplorer.Selection.Item(1)
Set ReplyEmail = Application.CreateItemFromTemplate("C:\Temp\Untitled.oft")
'// for the Subject
'// SR23443354|Replacement request = Bla Bla SR23443354|- Open
ReplyEmail.Subject = "Bla Bla " & "|" _
& Split(OrigEmail.Subject, "|")(0) _
& " - Open"
'// Process Mail body
'// Get the text of the message
'// and split it by paragraph
vText = Split(OrigEmail.Body, Chr(13)) ' Chr(13)) carriage return
' '// Check each line of text in the message body
For i = UBound(vText) To 0 Step -1
'// locate the text relating to the item required
'// Serial Number:
If InStr(1, vText(i), "Serial Number") > 0 Then
'// Split text line From ":"
vItem = Split(vText(i), Chr(58)) ' Chr(58) = :
SerialNum = vItem(1)
Debug.Print SerialNum ' Print Immediate Window
End If
'// Location:
If InStr(1, vText(i), "Location") > 0 Then
vItem = Split(vText(i), Chr(58))
Location = vItem(1)
End If
'// Summary:
If InStr(1, vText(i), "Summary") > 0 Then
vItem = Split(vText(i), Chr(58))
Summary = vItem(1)
End If
Next
' '// Now Update oft file
With ReplyEmail
.Body = Replace(.Body, "INC1", SerialNum)
.Body = Replace(.Body, "LOC", Location)
.Body = Replace(.Body, "SUMM", Summary)
End With
ReplyEmail.CC = ""
ReplyEmail.Display
Set OrigEmail = Nothing
Set ReplyEmail = Nothing
End Sub

Excel VBA for searching String within an Outlook Attachment, flagging email if match is found

Basically I have a list of 5000 strings populated in an Excel spreadsheet. I want VBA to go through the attachments in an Outlook Inbox and if it finds a string match, I want the particular email to be flagged. Here's the code I have so far
Sub attachsearch()
On Error GoTo bigerror
Dim ns As Namespace
Dim inbox As MAPIFolder
Dim subfolder As MAPIFolder
Dim item As Object
Dim atmt As Attachment
Dim filename As String
Dim i As Integer
Dim varresponse As VbMsgBoxResult
Dim workbk As Workbook
Dim SearchString As String
Set ns = GetNamespace("MAPI")
Set inbox = ns.GetDefaultFolder(olFolderInbox)
Set subfolder = inbox.Folders("test")
Set workbk = Workbooks.Open("C:\Users\John.Doe\Desktop\10 25 2016 Pricing Team Macro.xlsm")
i = 0
If subfolder.Items.Count = 0 Then
MsgBox "There are no emails to look at. Please stop wasting my time.", vbInformation, "Folder is Empty"
Exit Sub
End If
For Each item In subfolder.Items
For Each atmt In item.Attachments
For rwindex = 1 To 5000
SearchString = Workbooks("10 25 2016 Pricing Team Macro").Sheets("NDC Sort").Cells(rwindex, 1).Value
Below is the problem code, index proberty is not used correctly here, but I'm unsure what to use. I know that Microsoft indexes the words within the attachment because when I manually type in the search string in Outlook, it pulls up the email even though the string is only present within the attachment. So ultimately, my question is, how do I leverage that attachment index in VBA?
If atmt.Index Like "*" & Workbooks("10 25 2016 Pricing Team Macro").Sheets("NDC Sort").Cells(rwindex, 1).Value & "*" Then
i = i + 1
With item
.FlagRequest = "Follow up"
.Save
End With
End If
Next rwindex
Next atmt
Next item
If i > 0 Then
MsgBox "I found " & i & " attached files with a specific name."
Else
MsgBox "I didn't find any files"
End If
Set atmt = Nothing
Set item = Nothing
Set ns = Nothing
workbk.Close savechanges:=False
Exit Sub
bigerror:
MsgBox "something went wrong"
End Sub
Any help would be greatly appreciated, thanks in advance!
Here's a solution if you only need to search the contents PDFs, MSWord, and Excel. There's a different procedure for each. A caveat is that you need to have a version of Adobe that you pay for. This won't work on plain Adobe Reader. I've tested it a few times and it works, but it seems kind of chunky in some parts so I'm open to suggestions.
Sub attachsearch()
Dim ns As Namespace
Dim inbox As MAPIFolder
Dim subfolder As MAPIFolder
Dim item As Object
Dim atmt As Attachment
Dim tempfilepath As String
Dim tempfilename As String
Dim i As Integer
Dim workbk As Workbook
Dim LastRow As Long
Dim TextToFind As String
Dim Loc As Range
Dim Sh As Worksheet
Dim WS_Count As Integer
Dim x As Integer
Dim WS_Name As String
Set ns = GetNamespace("MAPI")
Set inbox = ns.GetDefaultFolder(olFolderInbox)
Set subfolder = inbox.Folders("test")
Set workbk = Workbooks.Open("C:\Users\John.Doe\Desktop\10 25 2016 Pricing Team Macro.xlsx")
LastRow = Workbooks("10 25 2016 Pricing Team Macro").Worksheets("NDC Sort").Cells(Worksheets("NDC Sort").Rows.Count, "A").End(xlUp).Row
i = 0
If subfolder.Items.Count = 0 Then
MsgBox "There are no emails to look at. Please stop wasting my time.", vbInformation, "Folder is Empty"
Exit Sub
End If
For Each item In subfolder.Items
For Each atmt In item.Attachments
If item.FlagStatus = Empty Then
If Right(atmt.Filename, 4) Like "xl**" Or Right(atmt.Filename, 3) Like "xl*" Then
tempfilepath = "O:\aaaTEST\"
tempfilename = Format(item.ReceivedTime, "yyyymmdd_hhnnss_") & item.SenderName & "_" & atmt.Filename
atmt.SaveAsFile tempfilepath & tempfilename
Workbooks.Open (tempfilepath & tempfilename)
Workbooks(tempfilename).Activate
WS_Count = Workbooks(tempfilename).Worksheets.Count
'Clearing any selections that may limit the search unintentionally
For x = 1 To WS_Count
With ActiveWorkbook.Worksheets(x)
.Select
.Cells(1, 1).Select
Application.CutCopyMode = False
End With
Next x
For rwindex = 2 To LastRow
If item.FlagStatus = Empty Then
TextToFind = Workbooks("10 25 2016 Pricing Team Macro").Sheets("NDC Sort").Cells(rwindex, 1).Value
If TextToFind <> "" Then
Workbooks(tempfilename).Activate
For x = 1 To WS_Count
With ActiveWorkbook.Worksheets(x)
.Select
.UsedRange.Select
Set Loc = .Cells.Find(TextToFind)
If item.FlagStatus = Empty Then
If Not Loc Is Nothing Then
i = i + 1
With item
.FlagRequest = "Follow up"
.Save
End With
End If
End If
Set Loc = Nothing
End With
Next x
End If
End If
Next rwindex
Workbooks(tempfilename).Close Savechanges:=False
End If
'PDF Check
If Right(atmt.Filename, 3) = "pdf" Then
tempfilename = "O:\aaaTEST\" & _
Format(item.ReceivedTime, "yyyymmdd_hhnnss_") & item.SenderName & "_" & atmt.Filename
atmt.SaveAsFile tempfilename
PDFPath = tempfilename
Set App = CreateObject("AcroExch.App", "")
Set AVDoc = CreateObject("AcroExch.AVDoc")
If AVDoc.Open(PDFPath, "") = True Then
AVDoc.BringToFront
For rwindex = 2 To 3593
If item.FlagStatus = Empty Then
TextToFind = Workbooks("10 25 2016 Pricing Team Macro").Sheets("NDC Sort").Cells(rwindex, 1).Value
If AVDoc.FindText(TextToFind, False, True, False) = True Then
i = i + 1
With item
.FlagRequest = "Follow up"
.Save
End With
End If
AVDoc.Close True
App.Exit
End If
Next rwindex
End If
End If
'MSWord check
If Right(atmt.Filename, 4) Like "doc*" Or Right(atmt.Filename, 3) Like "doc" Then
tempfilepath = "O:\aaaTEST\"
tempfilename = Format(item.ReceivedTime, "yyyymmdd_hhnnss_") & item.SenderName & "_" & atmt.Filename
atmt.SaveAsFile tempfilepath & tempfilename
Set wordapp = CreateObject("word.Application")
wordapp.Documents.Open Filename:=tempfilepath & tempfilename
wordapp.Visible = True
For rwindex = 2 To 5
If item.FlagStatus = Empty Then
TextToFind = Workbooks("10 25 2016 Pricing Team Macro").Sheets("NDC Sort").Cells(rwindex, 1).Value
If TextToFind <> "" Then
With wordapp.ActiveDocument.Content.Find
.ClearFormatting
.Execute FindText:=TextToFind
If .Found = True Then
i = i + 1
With item
.FlagRequest = "Follow up"
.Save
End With
End If
End With
End If
End If
Next rwindex
wordapp.ActiveDocument.Close Savechanges:=wdDoNotSaveChanges
wordapp.Quit Savechanges:=wdDoNotSaveChanges
End If
End If
Next atmt
Next item
Workbooks("10 25 2016 Pricing Team Macro").Close Savechanges:=False
If i > 0 Then
MsgBox "I found " & i & " attached files with a specific name."
Else
MsgBox "I didn't find any files"
End If
Set atmt = Nothing
Set item = Nothing
Set ns = Nothing
Exit Sub
End Sub

How can I count the instances of a certain string in an email and store that number?

So this has come up before, but the only answers given were to use Regular Expressions, but it's not making sense to me.
I already have a module that is copying text out of selected emails and dumping it into a CSV, I need it to also count instances of a certain string of text and also dump that count. What I have I bastardized from code I found here:
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim olItem As Outlook.MailItem
Dim vText As Variant
Dim sText As String
Dim vItem As Variant
Dim i As Long
Dim rCount As Long
Dim bXStarted As Boolean
Const strPath As String =
"F:\Scripting\Export\AEX_JUNIPER_LOGGING\Input\orders.csv" 'the path of the workbook
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("orders")
xlSheet.Rows(2 & ":" & xlSheet.Rows.Count).ClearContents
'Process each selected record
rCount = xlSheet.UsedRange.Rows.Count
For Each olItem In Application.ActiveExplorer.Selection
sText = olItem.Body
vText = Split(sText, Chr(13))
'Find the next empty line of the worksheet
rCount = rCount + 1
'Check each line of text in the message body
For i = UBound(vText) To 0 Step -1
If InStr(1, vText(i), "JOBID:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("A" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "RMA Number : ") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("B" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "DESTINATION WAREHOUSE : ") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("C" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "TRACKING NUMBER : ") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("D" & rCount) = Trim(vItem(1))
End If
Next i
xlWB.Save
Next olItem
xlWB.Close SaveChanges:=True
If bXStarted Then
xlApp.Quit
End If
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing
End Sub
How can I amend this to include the new code I need?
Without using regex, you can find the number of occurrences of a substring (subStr) within a string (str) using a similar algorithm as follows:
'Replaces all instances of substring with nothing, effectively removing all instances of it
newStr = Replace(str, subStr, "")
'Determine how many instances were removed
instancesOfSubStr = (len(str) - len(newStr)) / len(subStr)
At this point I imagine you can just accumulate it in a global variable after processing each cell.

VBA export certain data from Outlook to Excel running but producing nothing?

Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim olItem As Outlook.MailItem
Dim vText As Variant
Dim sText As String
Dim vItem As Variant
Dim i As Long
Dim rCount As Long
Dim bXStarted As Boolean
Const strPath As String = "C:\Users\Rob\Documents\Excel\Excel.xlsx" 'the path of the workbook
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
End If
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
bXStarted = True
End If
On Error GoTo 0
'Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(strPath)
Set xlSheet = xlWB.Sheets("Sheet1")
'Process each selected record
rCount = xlSheet.UsedRange.Rows.Count
For Each olItem In Application.ActiveExplorer.Selection
sText = olItem.Body
vText = Split(sText, Chr(13))
'Find the next empty line of the worksheet
rCount = rCount + 1
'Check each line of text in the message body
For i = UBound(vText) To 0 Step 1
If InStr(1, vText(i), "Destination -") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("a" & rCount) = Trim(vItem(1))
End If
Next i
xlWB.Save
Next olItem
xlWB.Close SaveChanges:=True
If bXStarted Then
xlApp.Quit
End If
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing
End Sub
This code is from online where I tried making it work for myself...
I need to extract Specific Data from emails (over 5000) and produce them on an Excel document. I've never touched VBA before only C#, Javascript & C++.
The code runs, the excel sheet updates to the current Date/time but nothing is produced?
Any help please?
I also get an error "Subscript out of range" for this line:
xlSheet.Range("A" & rCount) = Trim(vItem(1))
I think you need to change the second split delimiter to match the first one. This will take care of the Subscript error
Use this:
vItem = Split(vText(i), "Destination -")

How to fix Outlook script rule Error

I'm trying to run my code using rule script to only processes newly arrived message but it keeps throwing Error
What am I doing wrong on my code?
Option Explicit
Public Sub Test(Item As Outlook.MailItem)
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim vText As Variant
Dim sText As String
Dim vItem As Variant
Dim i As Long
Dim rCount As Long
Dim XStarted As Boolean
Dim FileName As String
Dim FilePath As String '// SaveAs CSV File Path
Dim sPath As String '// .CSV File Path
'// the path of the workbook
sPath = "C:\temp\temp.csv"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err <> 0 Then
Application.StatusBar = "Please wait while Excel source is opened ... "
Set xlApp = CreateObject("Excel.Application")
XStarted = True
End If
' On Error GoTo 0
'// Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(sPath)
Set xlSheet = xlWB.Sheets("Report")
'// Process received Mail
sText = Item.Body
vText = Split(sText, Chr(13)) ' Chr(13)) carriage return
'// Find the next empty line of the worksheet
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(xlUp).Row
rCount = rCount + 1
'// Check each line of text in the message body
For i = UBound(vText) To 0 Step -1
'// Customer Name
If InStr(1, vText(i), "Customer") > 0 Then
vItem = Split(vText(i), Chr(9)) ' Chr(9) horizontal tab
xlSheet.Range("A" & rCount) = Trim(vItem(1))
End If
'// Ref Number
If InStr(1, vText(i), "Order #") > 0 Then
vItem = Split(vText(i), Chr(9))
xlSheet.Range("B" & rCount) = Trim(vItem(1))
End If
'// Service Level
If InStr(1, vText(i), "Service Level") > 0 Then
vItem = Split(vText(i), Chr(9))
xlSheet.Range("J" & rCount) = Trim(vItem(1))
End If
Next i
FilePath = Environ("USERPROFILE") & "\Documents\Temp\"
FileName = Sheets(1).Range("B2").Value
xlWB.SaveAs FileName:=FilePath & FileName
'// Close & SaveChanges
xlWB.Close SaveChanges:=True
If XStarted Then
xlApp.Quit
End If
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set Item = Nothing
End Sub
Per Patrick.
You may have changed the VBA Project name. Go to Outlook Rules, Edit, re-assign the macro.
Also, it should FileName = xlWB.Sheets(1).Range("B2").Value And get rid of Application.StatusBar = ...
Thanks...