Download and Save Attachment from Email Automatically to Excel - excel

Currently my code listed below will copy body information from an incoming email and open the designated excel sheet and copy the contents onto the excel sheet and close it. I would also like to save attachments from incoming email to this designated path :C:\Users\ltorres\Desktop\Projects
I have tried this, but this code will not incorporate with outlook. I would have to run it with excel
Public Sub saveAttachtoDisk (itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim dateFormat As String
saveFolder = "C:\Users\ltorres\Desktop\Projects"
dateFormat = Format(Now, "yyyy-mm-dd H-mm")
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & dateFormat & objAtt.DisplayName
Set objAtt = Nothing
Next
End Sub
Const xlUp As Long = -4162
Sub ExportToExcel(MyMail As MailItem)
Dim strID As String, olNS As Outlook.NameSpace
Dim olMail As Outlook.MailItem
Dim strFileName As String
'~~> Excel Variables
Dim oXLApp As Object, oXLwb As Object, oXLws As Object
Dim lRow As Long
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
End If
Err.Clear
On Error GoTo 0
'~~> Show Excel
oXLApp.Visible = True
'~~> Open the relevant file
Set oXLwb = oXLApp.Workbooks.Open("C:\Users\ltorres\Desktop\Projects\Project 2\TemplateFinal\lighting.xlsm")
'~~> Set the relevant output sheet. Change as applicable
Set oXLws = oXLwb.Sheets("Multiplier")
lRow = oXLws.Range("A" & oXLws.Rows.Count).End(xlUp).Row + 1
'~~> Write to outlook
With oXLws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
Dim MyAr() As String
MyAr = Split(olMail.Body, vbCrLf)
For i = LBound(MyAr) To UBound(MyAr)
.Range("A" & lRow).Value = MyAr(i)
lRow = lRow + 1
Next i
'
End With
'~~> Close and Clean up Excel
oXLwb.Close (True)
oXLApp.Quit
Set oXLws = Nothing
Set oXLwb = Nothing
Set oXLApp = Nothing
Set olMail = Nothing
Set olNS = Nothing
End Sub

To add to #Om3r response, you could add this code (untested) to the ThisOutlookSession module:
Private WithEvents objNewMailItems As Outlook.Items
Dim WithEvents TargetFolderItems As Items
Private Sub Application_Startup()
Dim ns As Outlook.NameSpace
Set ns = Application.GetNamespace("MAPI")
'Update to the correct Outlook folder.
Set TargetFolderItems = ns.Folders.item("Mailbox - Luis") _
.Folders.item("Inbox") _
.Folders.item("Lighting Emails").Items
End Sub
Sub TargetFolderItems_ItemAdd(ByVal item As Object)
SaveAtmt_ExportToExcel item
End Sub
This will watch the Lighting Emails folder (or whatever folder you choose) and execute the SaveAtmt_ExportToExcel procedure whenever an email arrives in that folder.
This will mean that Excel will open and close for each email. It will also interrupt whatever else you're doing to open Excel and execute - so will probably want to update so it only opens Excel once and to run the Outlook rule to place the emails in the correct folder once a day rather than always on.

Try it this way...
Update SaveFolder = "c:\temp\" and Workbooks.Open("C:\Temp\Book1.xlsx")
Tested on Outlook 2010
Public Sub SaveAtmt_ExportToExcel(Item As Outlook.MailItem)
Dim Atmt As Outlook.Attachment
Dim SaveFolder As String
Dim DateFormat As String
Dim strID As String, olNS As Outlook.NameSpace
Dim olMail As Outlook.MailItem
Dim strFileName As String
'~~> Excel Variables
Dim oXLApp As Object, oXLwb As Object, oXLws As Object
Dim lRow As Long
Dim i As Long
SaveFolder = "c:\temp\"
DateFormat = Format(Now, "yyyy-mm-dd H mm")
For Each Atmt In Item.Attachments
Atmt.SaveAsFile SaveFolder & "\" & DateFormat & " " & Atmt.DisplayName
Next
strID = Item.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
End If
Err.Clear
On Error GoTo 0
'~~> Show Excel
oXLApp.Visible = True
'~~> Open the relevant file
Set oXLwb = oXLApp.Workbooks.Open("C:\Temp\Book1.xlsx")
'~~> Set the relevant output sheet. Change as applicable
Set oXLws = oXLwb.Sheets("Multiplier")
lRow = oXLws.Range("A" & oXLws.Rows.Count).End(xlUp).Row + 1
'~~> Write to outlook
With oXLws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
Dim MyAr() As String
MyAr = Split(olMail.body, vbCrLf)
For i = LBound(MyAr) To UBound(MyAr)
.Range("A" & lRow).Value = MyAr(i)
lRow = lRow + 1
Next i
'
End With
'~~> Close and Clean
oXLwb.Close (True)
oXLApp.Quit
Set oXLws = Nothing
Set oXLwb = Nothing
Set oXLApp = Nothing
Set olMail = Nothing
Set olNS = Nothing
Set Atmt = Nothing
End Sub

Related

How to export all mails form specific folder from Outlook to Excel

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.

Scan excel attachment cell(s) for specific text, and forward mail to correct recipient(s)

I am new to using VBA and I adapted code I found online. I am attempting to search an Excel attachment within an e-mail, for specific strings of text in specific cells, and if it finds the correct text, to forward the mail to the correct person.
Sub CheckAttachments(olItem As MailItem)
Const strPath As String = "C:\Users\KoderM16\Desktop"
Const strFindText As String = "Car"
Const strFindText2 As String = "Toy"
Const strFindText3 As String = "Grass"
Dim strFilename As String
Dim olAttach As Attachment
Dim xlApp As Object
Dim xlWB As Object
Dim xlSheet As Object
Dim bXStarted As Boolean
Dim bFound As Boolean
Dim Inbox As MAPIFolder
Dim MyItems As Items
Dim MyItem As MailItem
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
Set MyItems = Inbox.Items
Set MyItem = Application.ActiveExplorer.Selection(1)
Set MyItem = MyItem.Forward
If olItem.Attachments.Count > 0 Then
For Each olAttach In olItem.Attachments
If Right(LCase(olAttach.FileName), 3) = "xls" Or Right(LCase(olAttach.FileName), 4) = "xlsx" Then
strFilename = strPath & Format(olItem.ReceivedTime, "yyyymmdd-HHMMSS") & _
Chr(32) & olAttach.FileName
olAttach.SaveAsFile strFilename
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 read the data
Set xlWB = xlApp.Workbooks.Open(strFilename)
Set xlSheet = xlWB.Sheets("Sheet1")
If FindValue(strFindText, xlSheet) Then
MyItem.Recipients.Add "emailaddress1"
MyItem.Send
ElseIf FindValue(strFindText2, xlSheet) Then
MyItem.Recipients.Add "emailaddress2"
MyItem.Send
ElseIf FindValue(strFindText3, xlSheet) Then
MyItem.Recipients.Add "emailaddress3"
MyItem.Send
End If
xlWB.Close 0
If bXStarted Then xlApp.Quit
If Not bFound Then Kill strFilename
Exit For
End If
Next olAttach
End If
End Sub
Function FindValue(FindString As String, iSheet As Object) As Boolean
Dim Rng As Object
If Trim(FindString) <> "" Then
With iSheet.Range("B2")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=-4163, _
LookAt:=1, _
SearchOrder:=1, _
SearchDirection:=1, _
MatchCase:=False)
If Not Rng Is Nothing Then
FindValue = True
Else
FindValue = False
End If
End With
End If
End Function
Sub Test()
Dim olMsg As MailItem
On Error Resume Next
Set olMsg = ActiveExplorer.Selection.Item(1)
CheckAttachments olMsg
End Sub
The code searches the .xls attachment and if it finds the data in the sheet, it forwards the mail. However, I want to be able to point to multiple individual cells. There might be some unnecessary stuff in the code. I try to point to cell B2 near the bottom of the code but even if it finds the text in A1, it sends the mail.
'Section 1
Sub CheckAttachments(olItem As MailItem)
Const strPath As String = "Enter_Path_Here" 'Define a path for the temp file
Dim strFilename As String
Dim olAttach As Attachment
Dim xlSheet As Object
Dim bXStarted As Boolean
Dim bFound As Boolean
Dim Inbox As MAPIFolder
Dim MyItems As Items
'Section 2
'A new MyItem is required per mutually exclusive recipient as below
Dim MyItem As MailItem
Dim MyItemTwo As MailItem
Dim MyItemThree As MailItem
Dim MyItemFour As MailItem
Dim MyItemFive As MailItem
Dim MyItemSix As MailItem
'Section 3
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
Set MyItems = Inbox.Items
'Section 4
'A new MyItem is required per mutually exclusive recipient as below
Set MyItem = Application.ActiveExplorer.Selection(1)
Set MyItem = MyItem.Forward
Set MyItemTwo = Application.ActiveExplorer.Selection(1)
Set MyItemTwo = MyItemTwo.Forward
Set MyItemThree = Application.ActiveExplorer.Selection(1)
Set MyItemThree = MyItemTwo.Forward
Set MyItemFour = Application.ActiveExplorer.Selection(1)
Set MyItemFour = MyItemTwo.Forward
Set MyItemFive = Application.ActiveExplorer.Selection(1)
Set MyItemFive = MyItemTwo.Forward
Set MyItemSix = Application.ActiveExplorer.Selection(1)
Set MyItemSix = MyItemTwo.Forward
'Section 5
If olItem.Attachments.Count > 0 Then
For Each olAttach In olItem.Attachments
If Right(LCase(olAttach.FileName), 3) = "xls" Or Right(LCase(olAttach.FileName), 4) = "xlsx" Or Right(LCase(olAttach.FileName), 4) = "xlsm" Then 'Define the file types to search in
strFilename = strPath & Format(olItem.ReceivedTime, "yyyymmdd-HHMMSS") & _
Chr(32) & olAttach.FileName
olAttach.SaveAsFile strFilename
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 read the data
Set xlWB = xlApp.Workbooks.Open(strFilename)
Set xlSheet = xlWB.Sheets("Sheet1")
'Section 6
'A new xlSheet cell selection and If statement is required for mutually exclusive recipients as below. Multiple addresses can be added to one condition
If xlSheet.Range("A1").Value = "Enter_Value_To_Find" Then
MyItem.Recipients.Add "Enter_E-Mail_Address"
MyItem.Send
End If
If xlSheet.Range("B1").Value = "Enter_Value_To_Find" Then
MyItemTwo.Recipients.Add "Enter_E-Mail_Address"
MyItemTwo.Send
End If
If xlSheet.Range("F1").Value = "Enter_Value_To_Find" Then
MyItemThree.Recipients.Add "Enter_E-Mail_Address"
MyItemThree.Send
End If
If xlSheet.Range("C10").Value = "Enter_Value_To_Find" Then
MyItemFour.Recipients.Add "Enter_E-Mail_Address"
MyItemFour.Send
End If
If xlSheet.Range("D5").Value = "Enter_Value_To_Find" Then
MyItemFive.Recipients.Add "Enter_E-Mail_Address"
MyItemFive.Send
End If
If xlSheet.Range("E7").Value = "Enter_Value_To_Find" Then
MyItemSix.Recipients.Add "Enter_E-Mail_Addressa"
MyItemSix.Send
End If
'Section 7
xlWB.Close 0
If bXStarted Then xlApp.Quit
If Not bFound Then Kill strFilename
Exit For
End If
Next olAttach
End If
End Sub
Sub Test()
Dim olMsg As MailItem
On Error Resume Next
Set olMsg = ActiveExplorer.Selection.Item(1)
CheckAttachments olMsg
End Sub

Body of outlook email does not copy to excel

The following code works It will open up designated file from designated email. However it will not Seperate the body message into different line in excel, any suggestions?
For i = LBound(MyAr) To UBound(MyAr)
'~~> This will give you the contents of your email
'~~> on separate lines
Debug.Print MyAr(i)
Next i
End With
Const xlUp As Long = -4162
Sub ExportToExcel(MyMail As MailItem)
Dim strID As String, olNS As Outlook.NameSpace
Dim olMail As Outlook.MailItem
Dim strFileName As String
'~~> Excel Variables
Dim oXLApp As Object, oXLwb As Object, oXLws As Object
Dim lRow As Long
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
End If
Err.Clear
On Error GoTo 0
'~~> Show Excel
oXLApp.Visible = True
'~~> Open the relevant file
Set oXLwb = oXLApp.Workbooks.Open("C:\Users\ltorres\Documents\multiplier.xlsx")
'~~> Set the relevant output sheet. Change as applicable
Set oXLws = oXLwb.Sheets("Sheet1")
lRow = oXLws.Range("A" & oXLws.Rows.Count).End(xlUp).Row + 1
'~~> Write to outlook
With oXLws
Dim MyAr() As String
MyAr = Split(olMail.Body, vbCrLf)
For i = LBound(MyAr) To UBound(MyAr)
'~~> This will give you the contents of your email
'~~> on separate lines
Debug.Print MyAr(i)
Next i
End With
'~~> Close and Clean up Excel
oXLwb.Close (True)
oXLApp.Quit
Set oXLws = Nothing
Set oXLwb = Nothing
Set oXLApp = Nothing
Set olMail = Nothing
Set olNS = Nothing
End Sub
You can set lRow in the With statement, but you also need to add 1 row each time there is a line break as defined by your MyAr, try:
With oXLws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
Dim MyAr() As String
MyAr = Split(olMail.Body, vbCrLf)
For i = LBound(MyAr) To UBound(MyAr)
.Range("A" & lRow).Value = MyAr(i)
lRow = lRow + 1
Next i
End With

Need Outlook Attachments File Names ( or only extensions ) counts exported for selected emails into Excel

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.

Update current file

I'm creating code wherein Outlook will extract all emails to an existing Excel file.
The code works and extracts all emails from a selected folder. However, when I try to use the same code on a separate folder, let's say Sent Items, it doesn't extract the data and opens a Read only version of the Excel file.
I plan to leave Outlook and Excel Open.
How can I work with any Outlook folder and still update the Excel file?
Private Sub Application_NewMailv7()
Dim objNS As NameSpace
Dim objFolder As MAPIFolder
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim obj As Object
Dim objOL As Outlook.Application
Dim objItems As Outlook.Items
Dim myItem As MailItem
Dim myXLApp As Excel.Application
Dim myXLWB As Excel.Workbook
Dim StrBody As String
Dim TotalRows As Long, i As Long
Set objOL = Outlook.Application
Set objFolder = objOL.ActiveExplorer.CurrentFolder
Set objItems = objFolder.Items
Set myXLApp = New Excel.Application
myXLApp.Visible = True
Set myXLWB = myXLApp.Workbooks.Open("C:\Users\username\Desktop\Folder Name\SR Historyv2.xlsx")
Set excWks = myXLWB.Worksheets("Sheet1")
TotalRows = Sheets(1).Range("A65536").End(xlUp).Row
i = TotalRows + 1
For Each obj In objItems
If obj.Class = olMail Then
'Add a row for each field in the message you want to export
excWks.Cells(i, 1) = Format(obj.ReceivedTime, "mm/dd/yyyy")
excWks.Cells(i, 2) = obj.SenderEmailAddress
excWks.Cells(i, 3) = obj.Subject
i = i + 1
'myXLWB.Save
End If
Next
Set obj = Nothing
Set objItems = Nothing
Set objFolder = Nothing
Set objOL = Nothing
End Sub
Try the following and if you would like to run Outlook Rule, let me know I will update the answer
Option Explicit
Sub Excel()
Dim xlApp As Object 'Excel App
Dim xlWB As Object 'WorkBook
Dim xlSheet As Object
Dim rngCount As Long
Dim xlStarted As Boolean
Dim xlPath As String
Dim olExplorer As Explorer
Dim olSelection As Selection
Dim olItem As Outlook.MailItem
Dim olMsg As Object
Dim xlColA, xlColB, xlColC, xlColD As String
'// Path of the Workbook - update only -> "\Folder Name\Folder Name\Book1.xlsx"
xlPath = Environ("USERPROFILE") & _
"\Documents\Temp\Book1.xlsx"
'// Set up Excel Application
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(xlPath)
Set xlSheet = xlWB.Sheets("Sheet1") ' or use (1) or (Sheet Name)
'// Record msg
On Error Resume Next
'// Find the next empty line of the worksheet
rngCount = xlSheet.Range("A" & xlSheet.Rows.Count).End(-4162).Row
'// Get the values from Outlook
Set olExplorer = Application.ActiveExplorer
'// Select Outlook msg
Set olSelection = olExplorer.Selection
For Each olMsg In olSelection
Set olItem = olMsg
'// Info to collect
xlColA = olItem.ReceivedTime
xlColB = olItem.SenderName
xlColC = olItem.SenderEmailAddress
xlColD = olItem.To
'// Write it to Excel sheet
xlSheet.Range("A" & rngCount) = xlColA
xlSheet.Range("B" & rngCount) = xlColB
xlSheet.Range("C" & rngCount) = xlColC
xlSheet.Range("D" & rngCount) = xlColD
'// Go to Next row
rngCount = rngCount + 1
Next
'// Save & Close Excel.Application
xlWB.Close 1
If xlStarted Then
xlApp.Quit
End If
'// Clean up
Set olItem = Nothing
Set olMsg = Nothing
Set olExplorer = Nothing
Set xlApp = Nothing
Set xlWB = Nothing
Set xlSheet = Nothing
End Sub
Do you close the SR Historyv2 workbook after you run the script or do you want to keep it open the entire time? If you keep it open and run the script again it will open the workbook a second time and that will be read only. For the second question i would suggest you look into the ItemAdd event in Outlook. This will only work if Outlook is open. https://msdn.microsoft.com/en-us/library/office/aa171270(v=office.11).aspx
I got this code working properly
Set myXLApp = GetObject(, "Excel.Application")
'specify the History File
With myXLApp
.Workbooks("SR Historyv2.xlsx").Activate
End With
It keeps the file to open and lets the other macro access it without being read-only.

Resources