Batch printing attachments, with same name, from multiple emails - vba

I have emails in Outlook 2013, each with only one file attached called "Report.pdf".
I am trying to batch print all of the attachments from my selection of emails.
I found the below code which works if the attachments all have different names. Is it possible to amend this to print nearly 150 attachments which all have the same name?
The names of the reports don't matter, so feel free to add what you need to them inside the code.
Sub BatchPrintAllAttachmentsinMultipleEmails()
Dim objFileSystem As Object
Dim strTempFolder As String
Dim objSelection As Outlook.Selection
Dim objItem As Object
Dim objMail As Outlook.MailItem
Dim objAttachments As Outlook.Attachments
Dim objAttachment As Outlook.Attachment
Dim objShell As Object
Dim objTempFolder As Object
Dim objTempFolderItem As Object
Dim strFilePath As String
Dim DateFormat
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
strTempFolder = objFileSystem.GetSpecialFolder(2).Path & "\Temp for Attachments " & Format(Now, "YYYY-MM-DD_hh-mm-ss")
'Create a new temp folder
MkDir (strTempFolder)
Set objSelection = Outlook.Application.ActiveExplorer.Selection
For Each objItem In objSelection
If TypeOf objItem Is MailItem Then
Set objMail = objItem
Set objAttachments = objMail.Attachments
'Save all the attachments in the temp folder
For Each objAttachment In objAttachments
strFilePath = strTempFolder & "\" & objAttachment.FileName
objAttachment.SaveAsFile (strFilePath)
'Print all the files in the temp folder
Set objShell = CreateObject("Shell.Application")
Set objTempFolder = objShell.NameSpace(0)
Set objTempFolderItem = objTempFolder.ParseName(strFilePath)
objTempFolderItem.InvokeVerbEx ("print")
Next objAttachment
End If
Next
End Sub

You do not say why the code does not work if all the attachments have the same name. I assume it is because SaveAsFile wants to overwrite the last “Report.pdf” with the next “Report.pdf” before printing is finished.
My first thought was to add Kill strFilePath before the SaveAsFile. On reflection, I decided that would not work because Shell would still be printing the previous “Report.pdf” when you attempted to delete it.
I think the simplest approach would be:
Add
Dim Count as Long
to your Dims.
Replace strFilePath = strTempFolder & "\" & objAttachment.FileName by:
Count = Count + 1
strFilePath = strTempFolder & "\" & Count & objAttachment.FileName
This will create and print files named “1Report.pdf”, “2Report.pdf”, “3Report.pdf” and so on. I have used a prefix rather than the traditional suffix because it saves the bother of placing Count between the file name and the extension.
I assume you have some method of deleting all the attachments from the temporary folder.

Related

Save Outlook attachments after creating folder in local directory

I am trying to access the sub folder by name "MacroEnabled" in Inbox, find all the attachments in it and save them to local drive.
I use this code to create a folder by name "Documents" and save the attachments. However while doing the second iteration it says file already exist error "58".
Dim ns As NameSpace
Dim olFolder_Inbox As Folder
Dim olMail As MailItem
Dim olAttachment As Attachment
Dim FolderPath As String
Dim fso As Object
Dim File_Saved As String
'email service type
Set ns = GetNamespace("MAPI")
Set olFolder_Inbox = ns.GetDefaultFolder(olFolderInbox).Folders("MacroEnabled")
Set fso = CreateObject("Scripting.FileSystemObject")
FolderPath = "Documents"
For Each olMail In olFolder_Inbox.Items
If TypeName(olMail) = "MailItem" And olMail.Attachments.Count > 0 Then
fso.CreateFolder ("Documents")
For Each olAttachment In olMail.Attachments
olAttachment.SaveAsFile fso.BuildPath(FolderPath, olAttachment.FileName)
Next olAttachment
End If
Next olMail
Set ns = Nothing
Set fso = Nothing
End Sub
First of all FolderPath should present whole path eg. FolderPath = "C:\Documents"
If you need you can use relative path for example FolderPath = CurrentProject.Path & "\Documents"
Then you can use FolderExisits method in loop by adding following instruction:
If Not fso.FolderExists(FolderPath) Then fso.CreateFolder (FolderPath )
For Each olMail In olFolder_Inbox.Items
fso.CreateFolder ("Documents_path")
look at this and try to check if folder Documents exists before creating another

How to save all selected messages into a folder with their categories and received time?

I want to select messages in Outlook then copy them into text files with the categories and received time as the txt titles. Example if three messages are selected, I would like three text files.
Sub selectMSGToText()
Dim oMail As Outlook.MailItem
Set oMail = Application.ActiveExplorer.Selection.Item(1)
Dim sMail As Object
Set sMail = Application.ActiveExplorer.Selection
Dim categories As String: categories = oMail.categories
Dim rtimeAs String: rtime= oMail.ReceivedTime
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim path As String
path = "D:\test\"
Dim oFile As Object
For Each oMail In sMail
Set oFile = fso.CreateTextFile(path & categories & "|" & rtime & ".txt", True, True)
oFile.WriteLine "test"
oFile.Close
Set fso = Nothing
Set oFile = Nothing
Next oMail
End Sub
I expect all selected messages to be in folder D:\test as distinct txt files with their own categories and received time as title.
A | is not legal in a Windows file name, nor are the / or \ or : you likely have in the ReceivedTime string.
Change to:
Dim rtime As Date: rtime= oMail.ReceivedTime
And use something like:
Set oFile = fso.CreateTextFile(path & categories & "_" & Format$(rtime, "dd_mm_yy_hhmmss") & ".txt", True, True)
(This assumes categories will never contain illegal characters)
The 1st true you pass causes an existing file to be overwritten, so multiple emails received in the same second will be lost.
Set fso = Nothing
Needs to be outside the loop, else on the 2nd iteration it is Nothing.

Batch Print email attachments in order by date

Issue:
Hello, I have a macro, which saves me for a lot of clicking, but in the end not so much time, when it all comes down to it. The code allows me to mark everything within any mail folder. It will print the attachments within the email.
After this the error starts. Whenever I press this button, the items are ready and set to go, for a race to the printer. Meaning that whatever attachment that gets to the printer first, is the one that gets printed first. I then have to put everything in the right order when it has been printed.
My current code:
Sub BatchPrintAllAttachmentsinMultipleEmails()
Dim objFileSystem As Object
Dim strTempFolder As String
Dim objSelection As Outlook.Selection
Dim objItem As Object
Dim objMail As Outlook.MailItem
Dim objAttachments As Outlook.Attachments
Dim objAttachment As Outlook.Attachment
Dim objShell As Object
Dim objTempFolder As Object
Dim objTempFolderItem As Object
Dim strFilePath As String
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
strTempFolder = objFileSystem.GetSpecialFolder(2).Path & "\Temp for Attachments " & Format(Now, "YYYY-MM-DD_hh-mm-ss")
'Create a new temp folder
MkDir (strTempFolder)
Set objSelection = Outlook.Application.ActiveExplorer.Selection
For Each objItem In objSelection
If TypeOf objItem Is MailItem Then
Set objMail = objItem
Set objAttachments = objMail.Attachments
'Save all the attachments in the temp folder
For Each objAttachment In objAttachments
strFilePath = strTempFolder & "\" & objAttachment.FileName
objAttachment.SaveAsFile (strFilePath)
'Print all the files in the temp folder
Set objShell = CreateObject("Shell.Application")
Set objTempFolder = objShell.NameSpace(0)
Set objTempFolderItem = objTempFolder.ParseName(strFilePath)
objTempFolderItem.InvokeVerbEx ("print")
Next objAttachment
End If
Next
End Sub
Goal:
I would like the code to look for dates, and print the oldest first, and work its way up for the newest date. Is there by any chance, that I can put in a string, which gets the macro to "cool down" and send it to the printer in order, by the oldest date to the newest?

Print Outlook attachments without saving on hard drive

I have a VBA script which cycles through selected emails and prints all PDF attachments in said emails.
Currently, the script saves the PDF files to the hard drive and then opens and prints them.
Sub BatchPrintAllAttachmentsinMultipleEmails()
Dim objFileSystem As Object
Dim strTempFolder As String
Dim objSelection As Outlook.Selection
Dim objItem As Object
Dim objMail As Outlook.MailItem
Dim objAttachments As Outlook.Attachments
Dim objAttachment As Outlook.Attachment
Dim objShell As Object
Dim objTempFolder As Object
Dim objTempFolderItem As Object
Dim strFilePath As String
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
strTempFolder = objFileSystem.GetSpecialFolder(2).Path & "\Temp for Attachments " & Format(Now, "YYYY-MM-DD_hh-mm-ss")
strTempFolder = "W:\my documents\test"
MkDir (strTempFolder)
Set objSelection = Outlook.Application.ActiveExplorer.Selection
For Each objItem In objSelection
If TypeOf objItem Is MailItem Then
Set objMail = objItem
Set objAttachments = objMail.Attachments
'Save all the attachments in the temp folder
For Each objAttachment In objAttachments
strFilePath = strTempFolder & "\" & objAttachment.FileName
If InStr(strFilePath, ".pdf") <> 0 Or InStr(strFilePath, ".PDF") <> 0 Then
objAttachment.SaveAsFile (strFilePath)
Set objShell = CreateObject("Shell.Application")
Set objTempFolder = objShell.NameSpace(0)
Set objTempFolderItem = objTempFolder.ParseName(strFilePath)
objTempFolderItem.InvokeVerbEx ("print") 'try now
End If
Next objAttachment
End If
Next
End Sub
I am wondering if it is possible to execute this code without saving the files to the hard drive, i.e. just opening them from memory in VBA, print them, and have no trace of them on the hard drive?
Even "big" softwares, for example Outlook, are saving PDF-files to a local drive (temp-Folder) to open them in another program.
The problem here is that the PDF-reader needs a reference/path to the file you want to open.
I would suggest to delete the file from the drive after it is printed.

VBA Outlook - Run automatically for all email in inbox?

I have the following code which I am using to save an email attachment into a folder. I want to make this vba run automatically each time I open outlook and check all emails in my creditchecks#hewden.co.uk inbox (non default inbox).
At the moment though it only checks the email which is selected in the active inbox. can someone please show me how I can edit my code to get it to do what I need. thanks
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 withParts As String
Dim withoutParts 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\"
' 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
If Right(strFile, 3) = "pdf" Then
' Combine with the path to the Temp folder.
withParts = strFile
withoutParts = Replace(withParts, ".pdf", "")
strFile = strFolderPath & withoutParts & "\" & strFile
' Save the attachment as a file.
objAttachments.item(i).SaveAsFile strFile
End If
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
Just need to edit some lines. Use something like objOL.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders("credutchecks#hewden.co.uk") to a folder in the same level of your Inbox folder. Here is your code modified:
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 withParts As String
Dim withoutParts 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
'Istead set this to the selected objects you just need to set to your email folder
'This is for a inbox same level folder
Set objSelection = objOL.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders("credutchecks#hewden.co.uk")
'This is for a folder inside the inbox folder
'Set objSelection = objOL.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Folders("credutchecks#hewden.co.uk")
' 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\"
' 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
If Right(strFile, 3) = "pdf" Then
' Combine with the path to the Temp folder.
withParts = strFile
withoutParts = Replace(withParts, ".pdf", "")
strFile = strFolderPath & withoutParts & "\" & strFile
' Save the attachment as a file.
objAttachments.item(i).SaveAsFile strFile
End If
Next i
End If
Next
ExitSub:
Set objAttachments = Nothing
Set objMsg = Nothing
Set objSelection = Nothing
Set objOL = Nothing
End Sub
To run it automatically when the Outlook starts just put it on the 'ThisOutlookSession' in the objects folder and name it 'Sub Application_Startup()'. Don't forget to enable macros before.