How to save attachments from selected Outlook conversations with VBA - vba

The logic is as follows:
Loop through selected messages.
Loop through attachments of selected messages.
Save attachments to pre-defined folder.
I am experiencing Runtime error 13.
I'm unsure which types are mismatched.
Public Sub SaveAttachments()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = 1 To lngCount
If objAttachments.Item(i).Type <> 5 Then
objAttachments.Item(i).SaveAsFile "C:\Users\Danny\Desktop\Attachments\" & objAttachments.Item(i).FileName
End If
Next i
End If
Next objMsg
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub

The Selection object may contain different Outlook item types - AppointmentItem, TaskItem, DocumentItem, i.e. not only the MailItem ones. So, I'd suggest declaring the item as object instead and then check out the message class or its type:
Dim individualItem As Object
For Each individualItem In Application.ActiveExplorer.Selection
'Perform some action on individualItem
Next Message

Related

Save Attachment on arriving email

I created an Outlook rule to save an attachment then move it to the Deleted Items folder. The code works when I highlight the arrived email in the Inbox then move the email to the Deleted Items folder.
When the new email arrives, it is saving the attachment(s) from different email in the inbox and not moving the email to the Deleted Items folder.
The Outlook rule is:
Apply this rule after the message arrives
from Sender
and with Gift Card in the subject
and on this computer only
run Project1.SaveAttachments
Public Sub SaveAttachments(MItem As Outlook.Mailitem)
Dim objOL As Outlook.Application
Dim objMsg As Outlook.Mailitem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim objNamespace As Outlook.NameSpace
Dim objDestFolder As Outlook.MAPIFolder
On Error Resume Next
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
strFolderpath = "Y:\"
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
strDeletedFiles = ""
If lngCount > 0 Then
For i = lngCount To 1 Step -1
strFile = objAttachments.Item(i).FileName
strFile = strFolderpath & strFile
objAttachments.Item(i).SaveAsFile strFile
Next i
Set objNamespace = objOL.GetNamespace("MAPI")
Set objDestFolder = objNamespace.GetDefaultFolder(olFolderDeletedItems)
objMsg.Move objDestFolder
End If
Next
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
Set objNamespace = Nothing
Set objDestFolder = Nothing
End Sub
According to my test, you could save email attachment and delete it using the below code:
Sub SaveAutoAttach()
Dim object_attachment As Outlook.attachment
Dim saveFolder As String
Dim oOutlook As Object
Dim oOlns As Object
Dim oOlInb As Object
Dim unRead, m As Object, att As Object
Dim some As String, other As String
Const olFolderInbox = 6
'~~> Get Outlook instance
Set oOutlook = GetObject(, "Outlook.application")
Set oOlns = oOutlook.GetNamespace("MAPI")
Set oOlInb = oOlns.GetDefaultFolder(olFolderInbox)
'~~> Check if there are any actual unread emails
Set unRead = oOlInb.Items.Restrict("[UnRead] = True")
If unRead.Count = 0 Then
MsgBox "NO Unread Email In Inbox"
Else
some = ""
other = ""
saveFolder = "D:\"
For Each m In unRead
If m.Attachments.Count > 0 Then
For Each object_attachment In m.Attachments
' Criteria to save .doc files only
If InStr(object_attachment.DisplayName, ".doc") Then
object_attachment.SaveAsFile saveFolder & "\" & object_attachment.DisplayName
End If
Next
End If
m.Delete
Next m
End Sub
For more information, please refer to this link:
Auto Download Outlook Email Attachment – Code in VBA by Topbullets.com

Outlook VBA Save Attachment is saving wrong attachment

I've been struggling with this for quite some time now, I don't get what I'm doing wrong.
I've got a script that will loop through emails in a folder. Then it checks the first 6 characters of the email subject. If it matches it must call a sub that will save the attachment to a specific folder, the only thing is that the file name changes every time depending on the subject of the email. Everything works fine if there is only 1 email in the folder, but as soon as there is more than 1 email it saves the last email attachment everytime but with the correct file name. So for example if you look at the underneath code it will save the attachment from ElseIf strLeft = "APPPE2" Then everytime with the filenames specified, eg report1.txt ... Help will be greatly appreciated.
Function LoopThroughFolder()
Dim objNS As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Set objNS = GetNamespace("MAPI")
Set objFolder = objNS.Folders.GetFirst ' folders of your current account
Set objFolder = objFolder.Folders("Inbox").Folders("PPB")
For Each Item In objFolder.Items
If TypeName(Item) = "MailItem" Then
' ... do stuff here ...
Set Msg = Item
Dim strSubject As String
strSubject = Item.Subject
Dim strLeft As String
strLeft = Left(strSubject, 6)
If strLeft = "APP DA" Then
Call SaveAttachments1
ElseIf strLeft = "APPGR1" Then
Call SaveAttachments2
ElseIf strLeft = "APPPE2" Then
Call SaveAttachments3
End If
End If
Next
End Function
Public Sub SaveAttachments1()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile1 As String
Dim strFolderpath As String
Dim strDeletedFiles As String
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
strFolderpath = "P:\database\"
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
strFile1 = "report.txt"
MsgBox (strFile1)
strFile1 = strFolderpath & strFile1
MsgBox (strFile1)
objAttachments.Item(i).SaveAsFile strFile1
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
Public Sub SaveAttachments2()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile2 As String
Dim strFolderpath As String
Dim strDeletedFiles As String
On Error Resume Next
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
strFolderpath = "P:\database\"
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
strFile2 = "report2.txt"
MsgBox (strFile2)
strFile2 = strFolderpath & strFile2
MsgBox (strFile2)
objAttachments.Item(i).SaveAsFile strFile2
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
Public Sub SaveAttachments3()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile3 As String
Dim strFolderpath As String
Dim strDeletedFiles As String
On Error Resume Next
Set objOL = CreateObject("Outlook.Application")
Set objSelection = objOL.ActiveExplorer.Selection
strFolderpath = "P:\database\"
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
strFile3 = "report3.txt"
strFile3 = strFolderpath & strFile3
objAttachments.Item(i).SaveAsFile strFile3
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
Each of your SaveAttachments subs should have a objMsg parameter, which should be passed from LoopThroughFolder - there is no need to "re-find" the message just to save the attachments.
Untested but something like this:
Function LoopThroughFolder()
Dim objNS As Outlook.NameSpace, Item, Msg As Outlook.MailItem
Dim objFolder As Outlook.MAPIFolder
Set objNS = GetNamespace("MAPI")
Set objFolder = objNS.Folders.GetFirst ' folders of your current account
Set objFolder = objFolder.Folders("Inbox").Folders("PPB")
For Each Item In objFolder.Items
If TypeName(Item) = "MailItem" Then
' ... do stuff here ...
Set Msg = Item
Dim strSubject As String
strSubject = Msg.Subject
Dim strLeft As String
strLeft = Left(strSubject, 6)
If strLeft = "APP DA" Then
SaveAttachments1 Msg
ElseIf strLeft = "APPGR1" Then
SaveAttachments2 Msg
ElseIf strLeft = "APPPE2" Then
SaveAttachments3 Msg
End If
End If
Next
End Function
Public Sub SaveAttachments1(objMsg As Outlook.MailItem)
Dim objAttachments As Outlook.Attachments
Dim i As Long
Dim lngCount As Long
Dim strFolderpath As String
strFolderpath = "P:\database\"
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
For i = lngCount To 1 Step -1
objAttachments.Item(i).SaveAsFile strFolderpath & "report.txt"
Next i
End If
End Sub

Code unexpectedly stops after changing folder in Outlook

I have a macro1 that when it detects a new email in a certain folder it triggers another macro2 that goes to that specific folder, download all attachments, delete all emails and then goes back to inbox.
Macro1 runs well and trigger macro2.
The problem is: macro2 only runs halfway. When It executes, it runs only until the part of the code that sets the active folder to the one I desire. After that, it stops. When I run macro2 again, immediately after it stops, it works and download/delete the attachment.
It looks to me it is a single fix but I can't figure it out.
1-Macro1: If I get a new email in folder "Relatorio", it will run macro2
2-Macro2 will turn "Relatorio" active
it stops here ### if I run again, it proceeds
3-Macro2 will download all emails and attachments
4-Macro2 will delete all emails
5-Macro2 will change active folder to inbox back again
Macro2:
Dim objOL As Object 'As Outlook.Application
Dim objMsg As Object 'Outlook.MailItem
Dim objAttachments As Object 'As Outlook.Attachments
Dim objSelection As Object 'As Outlook.Selection
Dim objFolder As Object 'As Outlook.Folder
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
strFolderpath = "C:\Users\hopnere\Desktop\Dashboard\"
Set objOL = CreateObject("Outlook.Application")
Set objFolder = Session.GetDefaultFolder(olFolderInbox).Folders("Relatorio")
Set objOL.ActiveExplorer.CurrentFolder = objFolder
### stops here ###
Set objMsg = objOL.CreateItem(olMailItem)
Set objSelection = objOL.ActiveExplorer.Selection
For Each objMsg In objFolder.Items
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count 'check if there is an email with attachment
MsgBox lngCount
If lngCount > 0 Then
For i = lngCount To 1 Step -1
i = lngCount
strFile = strFolderpath & "Backend.xls" 'attachment destiny folder
' saves attachment
objAttachments.item(i).SaveAsFile strFile
' Delete attachment
objAttachments.item(i).Delete
' delete email
objMsg.Delete
Next i
End If
Next
Set objFolder = Session.GetDefaultFolder(olFolderInbox) 'setting inbox active
Set objOL.ActiveExplorer.CurrentFolder = objFolder
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
Set objFolder = Nothing
End Sub
Set objSelection = objOL.ActiveExplorer.Selection
Represents a set of Outlook items object currently selected in an Active explorer, That procedure is called only when a message is selected - Remove it.
Set objOL = CreateObject("Outlook.Application")
Also, there is no need to create a new Outlook Application instance in the Outlook VBA macro, Instead, you can use the Application property,
for example:
Set objMsg = Application.CreateItem(olMailItem)

VBA save email attachments with pdf extension to folder

I am using the following code to save attachments from an email into a folder, now I want to add a if clause or conditions which says only save attachments with a .pdf extension.
Can someone please show me how I can change my code to get this to happen, thanks in advance
Public Sub SaveAttachments()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim objAttachments As Outlook.Attachments
Dim objSelection As Outlook.Selection
Dim i As Long
Dim lngCount As Long
Dim strFile As String
Dim strFolderpath As String
Dim strDeletedFiles As String
' Get the path to your My Documents folder
On Error Resume Next
' Instantiate an Outlook Application object.
Set objOL = CreateObject("Outlook.Application")
' Get the collection of selected objects.
Set objSelection = objOL.ActiveExplorer.Selection
' The attachment folder needs to exist
' You can change this to another folder name of your choice
' Set the Attachment folder.
strFolderpath = "\\UKSH000-FILE06\Purchasing\New_Supplier_Set_Ups_&_Audits\ATTACHMENTS\TEST\"
' Check each selected item for attachments.
For Each objMsg In objSelection
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
' Use a count down loop for removing items
' from a collection. Otherwise, the loop counter gets
' confused and only every other item is removed.
For i = lngCount To 1 Step -1
' Get the file name.
strFile = objAttachments.Item(i).FileName
' Combine with the path to the Temp folder.
strFile = strFolderpath & strFile
' Save the attachment as a file.
objAttachments.Item(i).SaveAsFile strFile
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
You'll want to iterate through the attachments collection on your objMsg to find the PDF.
This will look like:
For each objAttachment in objMsg.Attachments
if Right(objAttachment.FileName, 3) = "pdf" then
objAttachment.SaveAsFile strFolderPath & strFile
end if
Next objAttachment
Just make sure you decalre objAttachment at the top with:
Dim objAttachment as Attachment
Updated with full code from your example:
Public Sub SaveAttachments()
Dim objOL As Outlook.Application
Dim objMsg As Outlook.MailItem 'Object
Dim strFile As String
Dim strFolderpath As String
Dim strDeletedFiles As String
' Get the path to your My Documents folder
On Error Resume Next
' Instantiate an Outlook Application object.
Set objOL = CreateObject("Outlook.Application")
' Get the collection of selected objects.
Set objSelection = objOL.ActiveExplorer.Selection
' The attachment folder needs to exist
' You can change this to another folder name of your choice
' Set the Attachment folder.
strFolderpath = "\\UKSH000-FILE06\Purchasing\New_Supplier_Set_Ups_&_Audits\ATTACHMENTS\TEST\"
' Check each selected item for attachments.
For Each objMsg In objSelection
For each objAttachment in objMsg.Attachments
if Right(objAttachment.FileName, 3) = "pdf" then
' Append the file name to the folder.
strFile = strFolderpath & objAttachment.FileName
' Save it
objAttachments.Item(i).SaveAsFile strFile
end if
Next objAttachment
Next objMsg
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub

Type Mismatch error when items in Inbox declared as mailitems

I have the following VBA code in Outlook to move mail to a personal folder if it is old. Here is the code:
I get an exception on the line Next objItem (looking at the watch it is set to nothing).
What would cause objItem to be null and thus cause a Type Mismatch exception in the Next objItem line?
Sub MoveOldMailFromInbox()
Dim objFolder As Outlook.MAPIFolder
Dim objNS As Outlook.NameSpace, objItem As Outlook.MailItem, mail As Outlook.MailItem
Set objNS = Application.GetNamespace("MAPI")
Dim Inbox As MAPIFolder
Set Inbox = objNS.GetDefaultFolder(olFolderInbox)
Dim mailToMove As New Collection
Dim EightyFiveDaysAgo As Date
EightyFiveDaysAgo = DateAdd("d", -85, Date)
Set objFolder = objNS.Folders("PersonalFolders").Folders("InboxOlderThan85Days")
If objFolder Is Nothing Then
MsgBox "This folder doesn't exist!", vbOKOnly + vbExclamation, "INVALID FOLDER"
End If
For Each objItem In Inbox.Items
If objFolder.DefaultItemType = olMailItem Then
If objItem.Class = olMail And objItem.ReceivedTime < EightyFiveDaysAgo Then
mailToMove.Add objItem
End If
End If
Next objItem
For Each mail In mailToMove
mail.UnRead = False
mail.Move objFolder
Next mail
Set objItem = Nothing
Set objFolder = Nothing
Set objNS = Nothing
End Sub
You're iterating through Inbox.Items but your variable objItem is defined as MailItem - an item in your inbox might not always be a MailItem.
Try
Dim objItem as Object