macro to download selected messages attachments - Problem about downloaded files count - vba

I changed some codes for getting selected messages attachments to my hard drive like below :
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
Dim Counter As Long
strFolderpath = "D:\attachments"
If (Dir$(strFolderpath, vbDirectory) = "") Then
MsgBox "'" & strFolderpath & "' not exist"
MkDir strFolderpath
MsgBox "'" & strFolderpath & "' we create it"
Else
MsgBox "'" & strFolderpath & "' exist"
End If
' Get the path to your My Documents folder
'strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
strFolderpath = strFolderpath & "\"
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 = strFolderpath
' Check each selected item for attachments.
Counter = 1
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 & Counter & "_" & strFile
' Save the attachment as a file.
objAttachments.Item(I).SaveAsFile strFile
Counter = Counter + 1
Next I
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
MsgBox "All Selected Attachments Have Been Downloaded ..."
End Sub
my goal email uses imap service...
this vb codes works perfect!
but my problem is when download is finished we have not All needed files in attachments folder! (just some of them are there)
I have 450 UNREAD emails in my inbox that all of them have attachmen/s...
but we only have 200 files in attachments folder! (created by upper codes)
how can I fix this issue?
it seems this problem is in relationship with Unread Messages And My ADSL speed (but it should n't , I don't know?!)
when u read an email it seems Outlook does some stuff with that email and so next time that email runs faster because of it's caching.
how can I do this job for my unread emails with upper codes?
or is there any idea about this problem?
at last I would be really appreciate
for review and add or correct my codes
EDITION After comments :
my new code is like below :
Public Sub SaveAttachments()
Dim OlApp As Outlook.Application
Dim Inbox As MAPIFolder
Dim Item As Object
Dim ItemAttachments As Outlook.Attachments
Dim ItemAttachment As Object
Dim ItemAttCount As Long
Dim strFolderpath As String
Dim strFileName As String
Dim Counter As Long
Dim ItemsCount As Long
Dim ItemsAttachmentsCount As Long
strFolderpath = "d:\attachments"
If (Dir$(strFolderpath, vbDirectory) = "") Then
MsgBox "'" & strFolderpath & "' not exist"
MkDir strFolderpath
MsgBox "'" & strFolderpath & "' we create it"
Else
MsgBox "'" & strFolderpath & "' exist"
End If
' Get the path to your My Documents folder
'strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
strFolderpath = strFolderpath & "\"
'On Error Resume Next
' Instantiate an Outlook Application object.
Set OlApp = CreateObject("Outlook.Application")
Set Inbox = OlApp.ActiveExplorer.CurrentFolder
Counter = 1
ItemsCount = 0
ItemsAttachmentsCount = 0
For Each Item In Inbox.Items
ItemsCount = ItemsCount + 1
For Each ItemAttachment In Item.Attachments
ItemsAttachmentsCount = ItemsAttachmentsCount + 1
' Get the file name.
strFileName = ItemAttachment.FileName
' Combine with the path to the Attachments folder.
strFileName = strFolderpath & Counter & "_" & strFileName
' Save the attachment as a file.
ItemAttachment.SaveAsFile strFileName
Counter = Counter + 1
Next ItemAttachment
Next Item
ExitSub:
Set ItemAttachment = Nothing
Set ItemAttachments = Nothing
Set Item = Nothing
Set Inbox = Nothing
Set OlApp = Nothing
MsgBox "All Selected Folder Attachments Have Been Downloaded ..."
MsgBox "ItemsCount : " & ItemsCount
MsgBox "ItemsAttachmentsCount : " & ItemsAttachmentsCount
End Sub
but the previous problem is still there
all of my emails in inbox(SELECTED FOLDER FOR UPPER CODE) are 455 (5 Read + 450 Unread)
MsgBox "ItemsCount : " & ItemsCount returns -> 455
MsgBox "Sum Of All ItemAttCount : " & ItemsAttachmentsCount returns 200 or a bit more
any idea?

A possible problem is that not all your messages are selected in the explorer. Your code requires the messages to be selected in the current Outlook explorer window.
Try printing the count of selected e-mails:
Set objSelection = Application.ActiveExplorer.Selection
Debug.Print objSelection.Count
If the result (visible in the debug window) is not 450, then not all your 450 messages are selected, and that's why some of them are ignored.
EDIT: According to your updated question, the code correctly finds all the e-mail messages, but only some of the attachments. This calls for some good old-fashioned debugging, beyond what can be answered on this website.
Try Debug.Print Item.Attachments.Count at the beginning of the For Each Item... loop. Is the attachment count sometimes zero? For which messages is it zero?
EDIT 2: You speculate that there is some kind of caching of attachment for opened mails. To test this (and to solve the problem if this is indeed the issue), you could open the mail items before saving the attachments (and then close the mail item when done). This can be done like this:
For Each Item In Inbox.Items
' Open the mail item
Item.Display
' Your code to save the attachments goes here.
' Close the mail item
Item.Close olDiscard
Next Item

Related

VB.net - Read .msg file from the shared folder and extract the attachments inside it

I'm completely new to VB and I'm trying to extract the attachment which is saved available inside the .msg file using the below code.
Could someone help me if this is the right approach to do this ?
I'm facing below compiler errors. Could someone help me how to resolve this issue ?
Outlook.Attachment is not defined.
End Sub' must be preceded by a matching 'Sub'
Reference to a non-shared member requires an object reference.
Statement cannot appear within a method body. End of method assumed
Method arguments must be enclosed in parentheses.
Type 'Outlook.MailItem' is not defined.
Sub SaveOlAttachments()
Dim msg As Outlook.MailItem
Dim att As Outlook.Attachment
Dim strFilePath As String
Dim strAttPath As String
Dim strFile As String
strFilePath = "C:\Users\...\Desktop\Test\"
strAttPath = "C:\Users\...\extracted attachment\"
strFile = Dir(strFilePath & "<Doc Name>.msg")
Do While Len(strFile) > 0
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
If msg.Attachments.Count > 0 Then
For Each att In msg.Attachments
att.SaveAsFile strAttPath & att.FileName
Next
End If
strFile = Dir
Loop
End Sub
First of all, check out the file path where you try to find the template:
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
The strFilePath string may include the file name already:
strFile = Dir(strFilePath & "<Doc Name>.msg")
Second, make sure attachments are saved using unique file names:
att.SaveAsFile strAttPath & att.FileName
The FileName string can be the same in different emails. I'd recommend adding IDs or the current time and etc. to the file name to uniquely name attached files on the disk.
Here is the code we use to grab a daily report attachment. I left a few commented statements in case you might need them (we didn't).
Sub Extract_Outlook_Email_Attachments()
On Error GoTo ErrHandler
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim folder As MAPIFolder
Dim OutlookMail As Variant
Dim i As Integer
Dim olNS As Outlook.Namespace
Dim objOwner As Outlook.Recipient
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Dim saveFolder As String
saveFolder = strAttPath ' SAVE THE ATTACHMENT TO
'this bit is added to get a shared email
Set objOwner = OutlookNamespace.CreateRecipient("SHARED FOLDER NAME")
objOwner.Resolve
If objOwner.Resolved Then
Debug.Print "Outlook GB Fulfillment is good."
Set folder = OutlookNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) 'can use olFolderInbox or olFolderSentMail
End If
'Write mail to spreadsheet - create named range, from and to dates on the spreadsheet
i = 1
For Each OutlookMail In folder.Items
' Debug.Print "SenderEmailAddress: " & OutlookMail.SenderEmailAddress
'If OutlookMail.SenderEmailAddress = "no-reply#OurCompany.com" Then
If OutlookMail.subject = "Daily Report" Then
' If OutlookMail.SenderName = "no-reply#OurCompany.com" And OutlookMail.Subject = "Daily New Subscriber Plan Election Fulfillment" And OutlookMail.Attachments(1) = "NewSubscriberPlanElectionFulfillment_Subscription.xls" Then
Debug.Print "Received: " & OutlookMail.ReceivedTime
Debug.Print "Attach: " & OutlookMail.Attachments(1)
dateformat = Format(OutlookMail.ReceivedTime, "m-d-yy")
Debug.Print dateformat
FName = dateformat & " " & OutlookMail.Attachments(1).fileName
Debug.Print "FName: " & FName
Dim strFileExists As String
strFileExists = Dir(saveFolder & FName)
If strFileExists = "" Then
' MsgBox "The selected file doesn't exist"
Else
' MsgBox "The selected file exists"
Exit Sub
End If
OutlookMail.Attachments(1).SaveAsFile saveFolder & FName
Set outAttachment = Nothing
End If
Next OutlookMail
Set folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
ErrHandler:
Debug.Print Err.Description
End Sub
Instead of using CreateItemFromTemplate, you can use Namespace.OpenSharedItem to open an MSG file.
You also need to add Outlook to your VB.Net project references.

Outlook Save multiple attachments using the subject line, and incrementing that name

I've spent a couple of weeks playing with VBA, I am not by any means an expert on this.
What I'm looking for is a modification of this code.
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 Integer
Dim lngCount As Integer
Dim strFile As String
Dim strFolderpath As String
Dim strFileName As String
Dim objSubject As String
Dim strDeletedFiles As String
' Get the path to your My Documents folder
'strFolderpath = CreateObject("WScript.Shell").SpecialFolders(16)
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 = "C:\Users\demkep\Documents\"
' Check each selected item for attachments.
For Each objMsg In objSelection
'Set FileName to Subject
objSubject = objMsg.Subject
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.
strFileName = objSubject & ".pdf"
' Combine with the path to the Temp folder.
strFile = strFolderpath & strFileName
Debug.Print 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
It is the closest to what I am trying to accomplish.
However when I get an email with multiple attachments, it will simply overwrite the last file. if possible. I'd like it to save (sometimes up to 30 .pdf files) as "emailsubject, emailsubject(1), emailsubject(2), emailsubject(3)" etc...
any help would be appreciated.
You are not changing the filename within the loop. Something like
strFileName = objSubject & "(" & i & ").pdf"
should take care of that.
If you only want numbers if there is more than one attachment you can check lngCount before setting the name or use IIf
If lngCount > 1 Then
strFileName = objSubject & "(" & i & ").pdf"
Else
strFileName = objSubject & ".pdf"
End If
Or
strFileName = objSubject & IIf(lngCount>1, "(" & i & ")", "") & ".pdf"
You shouldn't use On Error Resume Next on your whole sub btw.
Here is Function that will do exactly what you need
Function UniqueName(FilePath As String) As String
Dim FSO As Object
Set FSO = CreateObject("Scripting.FilesystemObject")
Dim FileName As String
FileName = FilePath
Dim Ext As String
Ext = Chr(46) & FSO.GetExtensionName(FilePath)
Dim i As Long
i = 1
Do While FSO.FileExists(FileName)
FileName = Left(FilePath, Len(FilePath) - Len(Ext)) & " (" & i & ")" & Ext
i = i + 1
Loop
UniqueName = FileName
End Function
And change this strFile = strFolderpath & strFileName To strFile = UniqueName(strFolderpath & strFileName)

Dwonload attachment from specific sender and open in excel

I am rather new to VBA and was hoping to get some help on a project. To give you some background, I get an email in outlook about every 15 minutes with an excel attachment. I need to open the attachment once the email gets in and view it / compare it to the email that was sent 15 minutes prior. If there is a difference in the emails then I must preform an action. I was hoping to automate at least some of this process. Ideally, I could use a macro to scan my inbox for any new message from a particular sender. If it finds a message it could then check for an attachment and if the attachment is there it would download and open it.
In an ideal world the other thing I could do is compare the prior excel attachment to the current one and ping a message (alert) if it is different.
Any help would be much appreciated. As I said, I am new to VBA but I am trying my best to understand functions.
This should get you started. Assuming you have selected the e-mail in outlook:
Sub check_for_changes()
'Created by Fredrik Östman www.scoc.se
Dim myOlApp As New Outlook.Application
Dim myOlExp As Outlook.Explorer
Dim myOlSel As Outlook.Selection
Set myOlExp = myOlApp.Explorers.Item(1)
Set myOlSel = myOlExp.Selection
Set mymail = myOlSel.Item(1)
Dim myAttachments As Outlook.Attachments
Set myAttachments = mymail.Attachments
Dim Atmt As Attachment
Set Atmt = myAttachments(1)
new_file_name = "C:\tmp\new_received_file.xlsx"
old_file_name = "C:\tmp\old_received_file.xlsx"
FileCopy new_file_name, old_file_name
Atmt.SaveAsFile new_file_name
Dim eApp As Object
Set eApp = CreateObject("Excel.Application")
eApp.Application.Visible = True
Dim new_file As Object
eApp.workbooks.Open new_file_name
Set new_file = eApp.ActiveWorkbook
Dim old_file As Object
eApp.workbooks.Open old_file_name
Set old_file = eApp.ActiveWorkbook
'Find range to compare
start_row = old_file.sheets(1).usedrange.Row
If new_file.sheets(1).usedrange.Row > start_row Then start_row = new_file.sheets(1).usedrange.Row
end_row = old_file.sheets(1).usedrange.Row + old_file.sheets(1).usedrange.Rows.Count
If new_file.sheets(1).usedrange.Rows.Count + new_file.sheets(1).usedrange.Row > end_row Then end_row = new_file.sheets(1).usedrange.Rows.Count + new_file.sheets(1).usedrange.Row
start_col = old_file.sheets(1).usedrange.Column
If new_file.sheets(1).usedrange.Column > start_col Then start_col = new_file.sheets(1).usedrange.Column
end_col = old_file.sheets(1).usedrange.Column + old_file.sheets(1).usedrange.Columns.Count
If new_file.sheets(1).usedrange.Columns.Count + new_file.sheets(1).usedrange.Column > end_row Then end_row = new_file.sheets(1).usedrange.Columns.Count + new_file.sheets(1).usedrange.Column
'Check all cells
something_changed = False
For i = start_row To end_row
For j = start_col To end_col
If new_file.sheets(1).Cells(i, j) <> old_file.sheets(1).Cells(i, j) Then
new_file.sheets(1).Cells(i, j).Interior.ColorIndex = 3 'Mark red
something_changed = True
End If
Next j
Next i
If something_changed Then
new_file.Activate
Else
new_file.Close
old_file.Close
If eApp.workbooks.Count = 0 Then eApp.Quit
MsgBox "No changes"
End If
End Sub
Interesting question, I'll get you started with the outlook part. You'll probably want to split the question between Outlook and Excel.
Here is some code I use to save every attachment I have been sent in Outlook to save space.
Public Sub SaveAttachments()
Dim objOL As Outlook.Application
Dim pobjMsg As Outlook.MailItem 'Object
Dim objSelection As Outlook.Selection
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
For Each pobjMsg In objSelection
SaveAttachments_Parameter pobjMsg
Next
ExitSub:
Set pobjMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
MsgBox "Export Complete"
End Sub
Public Sub SaveAttachments_Parameter(objMsg As MailItem)
Dim objAttachments As Outlook.Attachments
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
strFolderpath = "C:\Users\******\Documents\Reports\"
'On Error Resume Next
' Set the Attachment folder.
strFolderpath = strFolderpath & "Outlook Attachments\"
' Get the Attachments collection of the item.
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
If lngCount > 0 Then
' We need to 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
' Save attachment before deleting from item.
' Get the file name.
strFile = objAttachments.Item(i).FileName
If Right(strFile, 4) = ".png" Or Right(strFile, 4) = ".jpg" Or Right(strFile, 4) = ".gif" Then
GoTo cont
End If
' Combine with the path to the Temp folder.
strFile = strFolderpath & objMsg.SenderName & "." & Format(objMsg.ReceivedTime, "yyyy-MM-dd h-mm-ss") & "." & strFile
' Save the attachment as a file.
objAttachments.Item(i).SaveAsFile strFile
' Delete the attachment - You might not want this part
'objAttachments.Item(i).Delete
'write the save as path to a string to add to the message
'check for html and use html tags in link
If objMsg.BodyFormat = olFormatHTML Then
strDeletedFiles = strDeletedFiles & vbCrLf & "<file://" & Replace(strFile, " ", "%20") & ">"
Else
strDeletedFiles = strDeletedFiles & vbCrLf & "<file://" & Replace(strFile, " ", "%20") & ">"
End If
cont:
Next i
' Adds the filename string to the message body and save it
' Check for HTML body
If objMsg.BodyFormat = olFormatHTML Then
objMsg.Body = "The file(s) were saved to " & strDeletedFiles & vbCrLf & objMsg.Body
Else
objMsg.HTMLBody = "The file(s) were saved to " & strDeletedFiles & vbCrLf & objMsg.HTMLBody
End If
objMsg.Save
End If
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objOL = Nothing
End Sub
The part in the code which says
If Right(strFile, 4) = ".png" Or Right(strFile, 4) = ".jpg" Or Right(strFile, 4) = ".gif" Then
GoTo cont
you could change to something like:
If objMsg.SenderName = "John Smith" Then
GoTo cont
that way it will only save the attachment from that specific sender.
Then, once you have two or more files, you can load the files using another macro in excel and compare the two files, then send you an email if there are any discrepancies.
Hope that gets you started.

Save attachments to a folder in outlook and rename them

I am trying to save outlook attachments to a folder and where the filename already exists save the newer file under a different name so as not to save over the existing file....perhaps just give an extension "v2" or even "v3" if "v2" exists.
I came across this answer but am finding that the newer file is saved over the existing file
Save attachments to a folder and rename them
I have used the below code;
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
strFolderpath = "C:\Users\Owner\my folder is here"
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
' Set the Attachment folder.
strFolderpath = strFolderpath & "\my subfolder is here\"
' Check each selected item for attachments. If attachments exist,
' save them to the strFolderPath folder and strip them from the item.
For Each objMsg In objSelection
' This code only strips attachments from mail items.
' If objMsg.class=olMail Then
' Get the Attachments collection of the item.
Set objAttachments = objMsg.Attachments
lngCount = objAttachments.Count
strDeletedFiles = ""
If lngCount > 0 Then
' We need to 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
' Save attachment before deleting from item.
' 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
' Delete the attachment.
objAttachments.Item(i).Delete
'write the save as path to a string to add to the message
'check for html and use html tags in link
If objMsg.BodyFormat <> olFormatHTML Then
strDeletedFiles = strDeletedFiles & vbCrLf & "<file://" & strFile & ">"
Else
strDeletedFiles = strDeletedFiles & "<br>" & "<a href='file://" & _
strFile & "'>" & strFile & "</a>"
End If
'Use the MsgBox command to troubleshoot. Remove it from the final code.
'MsgBox strDeletedFiles
Next i
' Adds the filename string to the message body and save it
' Check for HTML body
If objMsg.BodyFormat <> olFormatHTML Then
objMsg.Body = vbCrLf & "The file(s) were saved to " & strDeletedFiles & vbCrLf & objMsg.Body
Else
objMsg.HTMLBody = "<p>" & "The file(s) were saved to " & strDeletedFiles & "</p>" & objMsg.HTMLBody
End If
objMsg.Save
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
I am relatively new to vba so perhaps the solution is there but am not seeing it!
Take a look at my code below. It goes through all of the items in a specific Outlook folder (that you designate), goes through each attachment in each item, and saves the attachment in a specified file path.
'Establish path of folder you want to save to
Dim FilePath As Variant
FilePath = "C:\Users\Owner\my folder is here\my subfolder is here\"
Set FSOobj = CreateObject("Scripting.FilesystemObject")
'If path doesn't exist, create it. If it does, either do nothing or delete its contents
If FSOobj.FolderExists(FilePath) = False Then
FSOobj.CreateFolder FilePath
Else
' This code is if you want to delete the items in the existing folder first.
' It's not necessary for your case.
On Error Resume Next
Kill FilePath & "*.*"
On Error GoTo 0
End If
'Establish Outlook folders, attachments, and other items
Dim msOutlook As Outlook.NameSpace 'Establish Outlook NameSpace
Dim Folder As Outlook.MAPIFolder 'Establish Folder as a MAPIFolder
Dim messageAttachments As Outlook.Attachments
Set msOutlook = Application.GetNamespace("MAPI")
'Set the folder that contains the email with the attachment
Set Folder = msOutlook.GetDefaultFolder(olFolderInbox).Folders("FOLDER NAME HERE")
Set folderItems = Folder.Items
Dim folderItemsCount As Long
folderItemsCount = folderItems.Count
Dim number as Integer
number = 1
For i = 1 To folderItemsCount
'If you want to pull the attachments on some criteria, like the Subject of the email or
'the date received, you need to write an IF statement like:
'If InStr(Folder.Items(i).Subject, "SPECIFIC SUBJECT TEXT") Then
Set messageAttachments = folderItems.item(i).Attachments
lngCount = messageAttachments.Count 'This lets you pull more than one attachment per message
For thisAttachment = 1 To lngCount
messageAttachments.item(thisAttachment).SaveAsFile FilePath & "YOUR_CHOSEN_FILENAME" & number & ".xlsx"
number = number + 1
Next thisAttachment
Next i
EDIT
In order to delete the items after scraping the attachments, you would use the same code as above except you would also include folderItems.item(i).Delete. Also, since you are moving items, I switched to looping backwards in your for loop as to not mess up your iteration. I've written it below:
For i = folderItemsCount To 1 Step -1
'If you want to pull the attachments on some criteria, like the Subject of the email or
'the date received, you need to write an IF statement like:
'If InStr(Folder.Items(i).Subject, "SPECIFIC SUBJECT TEXT") Then
Set messageAttachments = folderItems.item(i).Attachments
lngCount = messageAttachments.Count 'This lets you pull more than one attachment per message
For thisAttachment = 1 To lngCount
messageAttachments.item(thisAttachment).SaveAsFile FilePath & "YOUR_CHOSEN_FILENAME" & number & ".xlsx"
number = number + 1
Next thisAttachment
folderItems.item(i).Delete
Next i
I hope this helps!

Macro error 'Cannot save the attachment. Don't have appropriate permission'

I have a button enabled macro in Outlook that looks through a shared inbox I have access to, finds Excel attachments in each mail item and then extracts them to a location on the network, creating a folder name with details of the subject of the email if it does not already exist.
When I first ran the macro about 3 months ago, I didn't encounter any error messages. However, running it again today brought up the following error message:
'Cannot save the attachment. You don't have the appropriate permission to perform this operation'
If I save the attachment to the location I want on the network, I have no problem doing so.
I used a msgbox prompt in the code to tell me what the attachment fullpath is before saving it. I'm not sure if this means anything but the atmt.pathname just brings up a blank messagebox.
What might be the issue? it seems as if the attachment I'm trying to save isn't actually there.
I have Outlook 2007 with Microsoft Exchange.
' Declare variables
Dim ns As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim myDestFolder As Outlook.MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim filename As String
Dim i As Integer
Dim iLoop As Integer
Dim ext As String
Dim Items As Outlook.Items
Dim counter
Dim Countofiloop, NumberOfInboxItems
Dim CategoryNameDetected As Boolean
Dim moveEmail As Boolean
Dim EmailSubject As String
Dim SiteNames As String
Dim targetRoute As String
Dim targetPath As String
' -------------------------- HERE SETS THE ROUTE TARGET PATH --------------------
targetRoute = "FolderPath\"
' -------------------------------------------------------------------------------
Dim Progress
Set ns = GetNamespace("MAPI")
Set Inbox = ns.Folders("Shared").Folders("Inbox")
Set Item = Inbox.Items
' Before the loop starts, set the vars
' Check Inbox for messages and exit if none found
If Inbox.Items.count = 0 Then
MsgBox "There are no messages to scan in the Inbox.", vbInformation, _
"Nothing Found"
Exit Sub
End If
' Check each message for attachments
NumberOfInboxItems = Inbox.Items.count
TotalInboxItems = NumberOfInboxItems
counter = 0
'========================== L O O P S T A R T S H E R E ===============
For i = 1 To NumberOfInboxItems
' assign email subject to as string
Set Item = Inbox.Items.Item(i)
EmailSubject = Item.Subject
counter = counter + 1
KPISorterForm.ListBox1.AddItem "Examining email " & counter & " out of " & Inbox.Items.count & " " & EmailSubject
DoEvents
' WHAT IS IT???----SET THE FILE PATH----------------------------------------
' does it have four digits in the subject line at the beginning?
If IsNumeric(Left(EmailSubject, 4)) = True And InStr(1, EmailSubject, "for") > 0 Then
SiteNames = Left(EmailSubject, InStr(1, EmailSubject, "for") - 2)
' Trim the string if ending with a space character
Do Until Not Right(SiteNames, 1) = " "
SiteNames = Left(SiteNames, Len(SiteNames) - 1)
Loop
SiteNames = Replace(SiteNames, " ", "")
' Save the attachment to specified location
For Each Atmt In Item.Attachments
' This filename path must exist! Change folder name as necessary.
' get here the extension
ext = Atmt.filename
ext = Right(ext, Len(ext) - InStrRev(ext, ".") + 1)
If Left(ext, 3) = ".xl" Then
targetPath = targetRoute & SiteNames
' SAVE ATTACHMENT
If testDir(targetPath) = False Then
KPISorterForm.ListBox1.AddItem "Creating directory " & targetPath
DoEvents
MkDir targetPath
End If
MsgBox Atmt.PathName
Atmt.SaveAsFile targetPath & "\" & SiteNames & ext
KPISorterForm.ListBox1.AddItem "Saving Item " & targetPath & "\" & SiteNames & ext
DoEvents
AttachmentsSaved = AttachmentsSaved + 1
moveEmail = True
End If
Next Atmt
End If
KPISorterForm.ListBox1.ListIndex = KPISorterForm.ListBox1.ListCount - 1
Next i
' Clear memory
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Set appOl = Nothing
Set myDestFolder = Nothing
HomeUserFormOutlook.ProgressFrame.Visible = False
HomeUserFormOutlook.ProgressBar.Width = 0
HomeUserFormOutlook.ProgressBar.Visible = False
DoEvents
Did you set your file attributes to vbNormal? Chances are it's in another mode like hidden or read-only....
When you specify the path in SaveAsFile(Path)
The path needs to include the name of the file that you are saving, so if you want the file to be saved with the same name use the .DisplayName property of the attachment item.