Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am trying to extract Data from emails by using this script I found online with some changes to run for my specific information:
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\ExcelTest.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
The information I have to extract from the emails are shown below in BOLD.
Destination State - Pennsylvania
Destination - Pittsburgh
UK Airport - London Gatwick
Airline - United Airlines
Flight Class - Premium - from £499
Depart Date - 27/07/2011
Return Date - 10/08/2011
Adults - 2
Children - 1
First Name - Andrew
Last Name - Leakey
Telephone - 07785 496123 // Number Is fake
Contact Email - AmdrewsEmail#Email.org.uk
When I run the code it says "Subscript out of range" and the debugger says it is occurring on this line.
xlSheet.Range("A" & rCount) = Trim(vItem(1))
Replace this:
vItem = Split(vText(i), Chr(58))
with this:
vItem = Split(vText(i),"-")
Related
I am trying to extract 2 fields from the following email.
How would you like your name to appear on the CERTIFICATE OF PARTICIPATION?
Joe Johnson (sample name)
Email Address Required Joe.Johnson#xxxmail.com
and the email address after "Required" which is Joe.Johnson#xxxmail.com
I want to import those two fields to Excel so I can populate a certificate and return it to the email address. Ultimately I would like to have code that would do all of the above but for the time being I would be happy just to get the following code to work.
I get a run time error on the following: Set xlSheet = xlWB.Sheets("Sheet1")
Sub ExtractEmailData()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim olItem As Object
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 = "D:\Joe\Documents\2018 TEAMS Certificate.xlsm" 'the path of the workbook
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), "PARTICIPATION?") > 0 Then
vItem = Split(vText(i), Chr(60))
vItem = Split(vItem(1), Chr(62))
xlSheet.Range("A" & rCount) = Trim(vItem(1))
End If
If InStr(1, vText(i), "Email Address Required") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("B" & 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
I am new to VBA.
Just to offer a simple fix, in case the problem is simple. Does "D:\Joe\Documents\2018 TEAMS Certificate.xlsm" definitely have a worksheet named "Sheet1"? If not, maybe you meant:
Set xlSheet = xlWB.Sheets(1)
I have macro which exports all data from Outlook INBOX to Excel along with time and date, but I need to set up to a particular folder to be copied in a same way.
How do I setup to specific subfolder?
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim objOL As Outlook.Application
Dim objFolder As Outlook.MAPIFolder
Dim objItems As Outlook.Items
Dim obj As Object
Dim olItem 'As Outlook.MailItem
Dim strColA, strColB, strColC, strColD, strColE, strColF As String
' Get Excel set up
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "\Documents\Book1.xlsx"
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
On Error Resume Next
' Open the workbook to input the data
' Create workbook if doesn't exist
Set xlWB = xlApp.Workbooks.Open(strPath)
If Err <> 0 Then
Set xlWB = xlApp.Workbooks.Add
xlWB.SaveAs FileName:=strPath
End If
On Error GoTo 0
Set xlSheet = xlWB.Sheets("Sheet1")
On Error Resume Next
' add the headers if not present
If xlSheet.Range("A1") = "" Then
xlSheet.Range("A1") = "Sender Name"
xlSheet.Range("B1") = "Sender Email"
xlSheet.Range("C1") = "Subject"
xlSheet.Range("D1") = "Body"
xlSheet.Range("E1") = "Sent To"
xlSheet.Range("F1") = "Date"
End If
'Find the next empty line of the worksheet
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row
' needed for Exchange 2016. Remove if causing blank lines.
rCount = rCount + 1
' get the values from outlook
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
Set objItems = objFolder.Items
For Each obj In objItems
Set olItem = obj
'collect the fields
strColA = olItem.SenderName
strColB = olItem.SenderEmailAddress
strColC = olItem.Subject
strColD = olItem.Body
strColE = olItem.To
strColF = olItem.ReceivedTime
' Get the Exchange address
' if not using Exchange, this block can be removed
Dim olEU As Outlook.ExchangeUser
Dim oEDL As Outlook.ExchangeDistributionList
Dim recip As Outlook.Recipient
Set recip = Application.Session.CreateRecipient(strColB)
If InStr(1, strColB, "/") > 0 Then
' if exchange, get smtp address
Select Case recip.AddressEntry.AddressEntryUserType
Case OlAddressEntryUserType.olExchangeUserAddressEntry
Set olEU = recip.AddressEntry.GetExchangeUser
If Not (olEU Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olOutlookContactAddressEntry
Set olEU = recip.AddressEntry.GetExchangeUser
If Not (olEU Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
Case OlAddressEntryUserType.olExchangeDistributionListAddressEntry
Set oEDL = recip.AddressEntry.GetExchangeDistributionList
If Not (oEDL Is Nothing) Then
strColB = olEU.PrimarySmtpAddress
End If
End Select
End If
' End Exchange section
'write them in the excel sheet
xlSheet.Range("A" & rCount) = strColA
xlSheet.Range("B" & rCount) = strColB
xlSheet.Range("c" & rCount) = strColC
xlSheet.Range("d" & rCount) = strColD
xlSheet.Range("e" & rCount) = strColE
xlSheet.Range("f" & rCount) = strColF
'Next row
rCount = rCount + 1
xlWB.Save
Next
' don't wrap lines
xlSheet.Rows.WrapText = False
xlWB.Save
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set olItem = Nothing
Set obj = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
You are using ActiveExplorer.CurrentFolder on your code, the CurrentFolder Property represents the current folder that is displayed in the explorer, code should run on any Active Explorer- just navigate on any folder that you like to run the code on.
If you prefer to change then You need to modify the following lines of code to set up your specified folder,
' get the values from outlook
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
To something like this
' get the values from outlook
Set objOL = Outlook.Application
Dim olNs As Outlook.NameSpace
Set olNs = objOL.GetNamespace("MAPI")
Set objFolder = olNs.GetDefaultFolder(olFolderInbox).Folders("SubFolder Name Here")
See Folder Object (Outlook) MSDN Use the Folders property of a NameSpace object or another Folder object to return the set of folders in a NameSpace or under a folder. You can navigate nested folders by starting from a top-level folder, say the Inbox, and using a combination of the Folder.Folders property, which returns the set of folders underneath a Folder object in the hierarchy,
Example:
GetDefaultFolder(olFolderInbox).Folders("SubFolderName") _
.Folders("SubFolderName")
and the Folders.Item method, which returns a folder within the Folders collection.
I wish to extract the filenames of the attachments I have received into the public folder and extract ( paste ) them into the excel file for easy analysis.
I have the below code however it is only selecting details of 1 email.
I wish to understand where it does wrong.
Option Explicit
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim rCount As Long
Dim bXStarted As Boolean
Dim enviro As String
Dim strPath As String
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim olItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Dim j As Long
Dim i As Integer
Dim Report As String
Dim attachment As attachment
Dim obj As Object
Dim strColB, strColC, strColD, strColE, strColF As String
' Get Excel set up
enviro = CStr(Environ("USERPROFILE"))
'the path of the workbook
strPath = enviro & "\Documents\test.xlsx"
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 the message record
On Error Resume Next
'Find the next empty line of the worksheet
rCount = xlSheet.Range("B" & xlSheet.Rows.Count).End(-4162).Row
' get the values from outlook
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each obj In Selection
Set olItem = obj
Set myAttachments = olItem.Attachments
'collect the fields
Next
For Each Selection In Selection
If Selection.Class = olMail Then
End If
For Each attachment In olItem.Attachments
Report = strColC & GetAttachmentInfo(attachment)
strColB = olItem.Attachments.Count
strColD = olItem.SenderEmailAddress
strColE = olItem.Categories
strColF = olItem.ReceivedTime
'write them in the excel sheet
xlSheet.Range("B" & rCount) = strColB
xlSheet.Range("c" & rCount) = Report
xlSheet.Range("d" & rCount) = strColD
xlSheet.Range("e" & rCount) = strColE
xlSheet.Range("f" & rCount) = strColF
'Next row
rCount = rCount + 1
Next
Next
xlWB.Close 1
If bXStarted Then
xlApp.Quit
End If
Set olItem = Nothing
Set obj = Nothing
Set currentExplorer = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
Public Function GetAttachmentInfo(attachment As attachment)
On Error GoTo On_Error
Dim Report
Dim strColA, strColB, strColC, strColD, strColE, strColF As String
GetAttachmentInfo = ""
Report = strColA & "Display Name: " & attachment.DisplayName
Report = strColC & "File Name: " & attachment.filename
GetAttachmentInfo = Report
Exiting:
Exit Function
On_Error:
MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Function
I do not have access to Outlook at the moment so the following is from studying the macro rather than trying to run it.
Public Function GetAttachmentInfo(attachment As attachment)
You need As String at the end if you want a value returned. You are using attachment both as a keyword and as the name of a parameter. Please rename the parameter.
Report = strColA & "Display Name: " & attachment.DisplayName
Report = strColC & "File Name: " & attachment.filename
strColA and strColA have be declared with a Dim statement but have not been given values so are blank. The second statement overwrites the value of Report set by the first.
I see examples of your use of On Error repeatedly. I did the same until I realised it was totally unhelpful. During development, you want the interpreter to stop on the statement giving the error so you know what to correct. In a production macro, released to non-technical users, you need something more friendly. I suggest you delete this code.
I cannot see why you are getting the name of the first attachment but not the other attachments. I suggest you correct these errors and then repost your revised code.
I am needing to copy some data from emails into a spreadsheet with a VBA, here is how the data is formatted in the email:
Items/Cost:
Item Description 1: $38.88
Quantity: 1
Item Description 2: $39.99
Quantity: 1
The Item Description is always different. Here is how I would like the output to be formatted when copied to Excel:
And here is my current code that I've tried:
Sub CopyToExcel()
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim xl
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
Dim rTime As Date
Const strPath As String = "C:\Tracking.xlsx" 'the path of the workbook
If Application.ActiveExplorer.Selection.Count = 0 Then
MsgBox "No Items selected!", vbCritical, "Error"
Exit Sub
EndIf
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")
xlWB.Sheets(1).Cells.Delete
'Process each selected record
rCount = xlSheet.UsedRange.Rows.Count
'cCount = xlSheet.UsedRange.Columns.Count
For Each olItem In Application.ActiveExplorer.Selection
sText = olItem.Body
rTime = Format(olItem.ReceivedTime, "mmmm d, yyyy")
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(vText(i), "Items/Cost:") Then
'ParseText = vText(i + 1) & vbCrLf
xlSheet.Range("A" & rCount) = Trim(vText(2))
vItem = Split(vText(4), Chr(58))
xlSheet.Range("B" & rCount) = Trim(vItem(1))
xlSheet.Range("A" & rCount + 1) = Trim(vText(6))
vItem = Split(vText(8), Chr(58))
xlSheet.Range("B" & rCount + 1) = Trim(vItem(1))
xlSheet.Range("A" & rCount + 2) = Trim(vText(10))
vItem = Split(vText(12), Chr(58))
xlSheet.Range("B" & rCount + 2) = Trim(vItem(1))
xlSheet.Range("A" & rCount + 3) = Trim(vText(14))
vItem = Split(vText(16), Chr(58))
xlSheet.Range("B" & rCount + 3) = Trim(vItem(1))
xlSheet.Range("A" & rCount + 4) = Trim(vText(18))
vItem = Split(vText(20), Chr(58))
xlSheet.Range("B" & rCount + 4) = Trim(vItem(1))
End If
Next i
xlWB.Save
Next olItem
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing
End Sub
Also I'm no expert at VB so any help is greatly appreciated.
UPDATE:
I figured out how to extract it the way I want to but it's sloppy and not dynamic. Sometimes there are 2 items and sometimes 5, so i need it to be adaptable. Can someone help me clean it up by chance?
Try the following
Option Explicit
Sub EmailToCsv()
Dim olItem 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 RowCount As Long
Dim xlStarted As Boolean
Dim FilePath As String
'// Update File location
FilePath = "C:\Temp\Tracking.xlsx"
'// Process Selections
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")
xlStarted = True
End If
On Error GoTo 0
'// Open the workbook to input the data
Set xlWB = xlApp.Workbooks.Open(FilePath)
Set xlSheet = xlWB.Sheets("Sheet1")
'// Process each selected record
For Each olItem In Application.ActiveExplorer.Selection
sText = olItem.Body
vText = Split(sText, Chr(13)) ' Chr(13)) carriage return
'// Find the next empty line of the worksheet
RowCount = xlSheet.Range("A" & xlSheet.Rows.Count).End(xlUp).Row
RowCount = RowCount + 1
'// Check each line of text in the message body
For i = UBound(vText) To 0 Step -1
'// Item Description 1
If InStr(1, vText(i), "Item Description 1:") > 0 Then
vItem = Split(vText(i), Chr(58)) ' Chr(58) ":"
xlSheet.Range("A" & RowCount) = "Item Description 1: " & Trim(vItem(1))
End If
'// Quantity
If InStr(1, vText(i), "Quantity:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("B" & RowCount) = Trim(vItem(1))
End If
'// Item Description 2
If InStr(1, vText(i), "Item Description 2:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("A" & RowCount + 1) = "Item Description 2: " & Trim(vItem(1))
End If
'// Quantity
If InStr(1, vText(i), "Quantity:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("B" & RowCount + 1) = Trim(vItem(1))
End If
Next i
Next olItem
'// SaveChanges & Close
xlWB.Close SaveChanges:=True
If xlStarted Then
xlApp.Quit
End If
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
Set olItem = Nothing
End Sub
An integer number follows "Purchase Order:" in the email body.
All emails follow this format. http://i.stack.imgur.com/1Ck9Q.jpg
The number is to be pasted into the next empty row of the Excel spreadsheet.
I have a spreadsheet on my desktop named "test" to try this with.
I've tried about 4 or 5 different VBA codes I found using Google with no luck.
A method to address this frequently asked question is shown here. http://social.msdn.microsoft.com/Forums/en-US/f1ab97d9-8fef-46cc-bbe0-e597370ed1c2/export-content-from-outlook-2010-emails-to-excel-spreadsheet?forum=isvvba
The code goes into Outlook not Excel.
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:\path\desktop\test.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), "Purchase order:") > 0 Then
vItem = Split(vText(i), Chr(58))
xlSheet.Range("A" & rCount) = Trim(vItem(1))
End If
' Where more data is to be extracted add more of these lines.
'If InStr(1, vText(i), "Second label:") > 0 Then
' vItem = Split(vText(i), Chr(58))
' xlSheet.Range("B" & rCount) = Trim(vItem(1))
'End If
'If InStr(1, vText(i), "Third label:") > 0 Then
' vItem = Split(vText(i), Chr(58))
' xlSheet.Range("C" & 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