Reputation: 1
I have been tasked with finding a way to easily save large numbers of email attachments.
I found code here:
https://www.slipstick.com/developer/code-samples/save-rename-outlook-email-attachments/
This requires the user to apply search terms to get their list of emails (e.g. received:27/02/2022 & keyword) then select all and run the macro.
For a large selection I get the message:
Your server administrator has limited the number of items you can open simultaneously. Try closing messages you have opened or removing attachments and images from unsent messages you are composing.
I understand that there are some built in limitations in Outlook and that the items remain open until the loop is closed.
Public Sub saveAttachtoDisk()
Dim itm As Outlook.MailItem
Dim currentExplorer As Explorer
Dim Selection As Selection
Dim strSubject As String, strExt As String
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim enviro As String
enviro = CStr(Environ("USERPROFILE"))
saveFolder = enviro & "\OneDrive - Deloitte (O365D)\Desktop\Attachment_Download\"
Set currentExplorer = Application.ActiveExplorer
Set Selection = currentExplorer.Selection
For Each itm In Selection
For Each objAtt In itm.Attachments
' get the last 5 characters for the file extension
strExt = Right(objAtt.DisplayName, 5)
' clean the subject
strSubject = Left(itm.Subject, 100)
ReplaceCharsForFileName strSubject, "-"
' put the name and extension together
File = saveFolder & strSubject & strExt
objAtt.SaveAsFile File
Next
Next
Set objAtt = Nothing
End Sub
Private Sub ReplaceCharsForFileName(sName As String, _
sChr As String _
)
sName = Replace(sName, "'", sChr)
sName = Replace(sName, "*", sChr)
sName = Replace(sName, "/", sChr)
sName = Replace(sName, "\", sChr)
sName = Replace(sName, ":", sChr)
sName = Replace(sName, "?", sChr)
sName = Replace(sName, Chr(34), sChr)
sName = Replace(sName, "<", sChr)
sName = Replace(sName, ">", sChr)
sName = Replace(sName, "|", sChr)
End Sub
I tried setting item to nothing within the loop:
For Each itm In Selection
For Each objAtt In itm.Attachments
' get the last 5 characters for the file extension
strExt = Right(objAtt.DisplayName, 5)
' clean the subject
strSubject = Left(itm.Subject, 100)
ReplaceCharsForFileName strSubject, "-"
' put the name and extension together
File = saveFolder & strSubject & strExt
objAtt.SaveAsFile File
Set itm = Nothing
Next
Next
Set objAtt = Nothing
End Sub
The mailbox is running in 'Use cached exchange mode' (I cannot change this) with 'download shared folders' unticked.
I understand from searching other threads that the "for each" loop keeps all items referenced until the loop ends.
Similar questions suggested the use of MAPITable.GetTable
but I haven't been able to find any example using this.
Upvotes: 0
Views: 137
Reputation: 66255
A couple things you can do:
Turn cached mode on - the error only occurs in online stores. Cached stores are not subject to the limit as your code would only be touching local objects.
Do not use for each
loops - they keep all their items referenced until the loop exits, use simple for
loops.
for i = 1 to Selection.Count
set itm = Selection(i)
set attachments = itm.Attachments
for j = 1 to attachments.Count
set attach = attachments(j)
...
set attach = Nothing
next j
set attachments = Nothing
set itm = Nothing
next i
Upvotes: 0