cllocc
asked on
Print attachments from an email automatically?
Is there a VB script or batch file that would allow me to print only the attachments of unread emails or emails in a certain folder in outlook 2010 automatically?
ASKER
Thanks! It seems that the script can print MS Office based files. can the script be tweaked to print files with .pdf or .img file extensions?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
great, I will be testing these out and let you know
Writing some code for you now...stand by
ASKER
ravindran_eee:
The concept would be the same.. You have to tweak the print subroutine a little bit based on the extension of the file.. For printing PDFs you can use something like this
Shell """C:\Program Files\Adobe\Reader 8.0\Reader\acrord32.exe"" /h /p """ + FileName + """", vbHide
http://www.howtogeek.com/howto/microsoft-office/batch-print-pdf-attachments-in-outlook/
I followed instructions on the website and after some tweaking of my own, the script is working now. I just need to test again on 2 more computers but I think your solution definitely works
ASKER
craisin:
Writing some code for you now...stand by
I definitely appreciate the effort, but I got the code from website working. Unless you are making something better that allows for more customization, otherwise the code off the website works great.
Thanks again.
ASKER
Ok, another issue. I created a public folder and added it to my favorites. PDFs will be coming to this public folder. How can i edit the script so that I can point the script to the public folder in my favorites? Currently, the path to the public folder in my favorites is displayed as follows:
\\Public Folders - user@mydomain.com\Favorite s
\\Public Folders - user@mydomain.com\Favorite
Yes, this code is much better.
Try it out.
You simply run the macro ""PrintAttachments" when an email message is selected.
The code will ascertain from the system what program is the executable program to operate on the attachment.
If the attachment is a ZIP file, it will examine each file in the zip and print each file (if possible) using recursion.
I have not yet ascertained the way of handling "html" or "htm" files, but perhaps someone else can shed a light on that.
Anyfile not printed whill be reported in a message after the macro runs.
Hope you like this idea.
Cheers
Chris
(craisin)
Try it out.
You simply run the macro ""PrintAttachments" when an email message is selected.
The code will ascertain from the system what program is the executable program to operate on the attachment.
If the attachment is a ZIP file, it will examine each file in the zip and print each file (if possible) using recursion.
I have not yet ascertained the way of handling "html" or "htm" files, but perhaps someone else can shed a light on that.
Anyfile not printed whill be reported in a message after the macro runs.
Hope you like this idea.
Cheers
Chris
(craisin)
Const MAX_FILENAME_LEN = 260
Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
Public Sub PrintAttachments()
'Code to print all attachments to an email
Dim oItem As Object
Dim oAttach As outlook.Attachment
Dim cNoPrint As String
Dim cTempFile As String
'obtain pointer to current email message
Set oItem = Application.ActiveInspector.CurrentItem
For Each oAttach In oItem.Attachments
cTempFile = "c:\" + oAttach.FileName
oAttach.SaveAsFile cTempFile
PrintFile cTempFile, cNoPrint
Next
If Len(cNoPrint) > 0 Then
MsgBox "The following files could not be printed:" + vbCrLf + _
"(No file Association or macro cannot yet handle extension)" + vbCrLf + vbCrLf + cNoPrint
End If
End Sub
Private Sub PrintFile(cTempFile As String, ByRef cNoPrint As String)
Dim i As Integer
Dim s As String
Dim nAt As Integer
Dim cExt As String
Dim cRun As String
Dim nFile As Integer
Dim cLine As String
Dim nRun As Long
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
s = String(MAX_FILENAME_LEN, 32)
'Retrieve the name and handle of the executable, associated with this file
i = FindExecutable(cTempFile, vbNullString, s)
If i > 32 Then
cRun = Left$(s, InStr(s, Chr$(0)) - 1)
nAt = InStrRev(cTempFile, ".")
cExt = Mid(cTempFile, nAt)
Select Case LCase(cExt)
Case ".zip"
cRun = fs.GetparentFoldername(cRun) + "\"
cRun = cRun + "wzunzip.exe " + Chr(34) + cTempFile + Chr(34) + " c:\TempZipExtract"
Shell cRun, vbHide
cTempFile = Dir("C:\TempZipExtract\*.*")
Do While cTempFile <> "" ' Start the loop
PrintFile "c:\TempZipExtract\" + cTempFile, cNoPrint 'Recursion!
cTempFile = Dir
Loop
Case ".pdf"
Shell cRun + "/h /p " + Chr(34) + cTempFile + Chr(34), vbHide
Case ".txt"
Shell "NOTEPAD.EXE /p " + cTempFile, vbHide
Case "html", "htm"
'code to print HTML files should be placed here
'then remove the following
Case Else
nRun = Shell(cRun + " " + cTempFile, vbHide)
If nRun = 0 Then
cNoPrint = cNoPrint + cTempFile
End If
End Select
Else
cNoPrint = cNoPrint + cTempFile
End If
End Sub
ASKER
so if i run this macro will it print attachments of emails in my entire inbox or a certain folder? Will my just navigating to the folder then running the macro be enough to only print the attachments in that folder or would i have to specify that folder in the code?
ASKER
You simply run the macro ""PrintAttachments" when an email message is selected.
Is there anyway to setup this up like the other macro so when it runs, it automatically checks a specified folder without the user having to select individual emails?
Further to the previous code, you could add code to go through all the emails in a certain folder (or multiple folders), and for each email that has not been read or in a certain folder to run the "PrintAttachments" code:
e.g. Dim oEmail As Object
For each oEmail in Application.ActiveInspecto r 'or folder name
PrintAttachments
Next
This is just an idea....it has not been tested. I am not sure whether "Application.ActiveInspect or" will work, but I have been working on this for 5 hours now and it is 3.40am...so I am off to bed! :-)
Cheers
Chris
(craisin)
e.g. Dim oEmail As Object
For each oEmail in Application.ActiveInspecto
PrintAttachments
Next
This is just an idea....it has not been tested. I am not sure whether "Application.ActiveInspect
Cheers
Chris
(craisin)
ASKER
Wow, sounds like you are in south east asia or my australia? thanks again for the hard work, I'll have to see if I can tweak the code to be able to print from a public folder in my favorites.
As far as your "favourites" go, in the code I have supplied, you can tweak lines 14 to 18 as follows:
For Each oAttach In oItem.Attachments
if right(lcase(oAttach.filena me),3) = "pdf" then
cTempFile = "\\Public Folders - " +
_user@mydomain.com\Favorit es\"+oAtta ch.Filenam e
else
cTempFile = "c:\" + oAttach.FileName
endif
oAttach.SaveAsFile cTempFile
PrintFile cTempFile, cNoPrint
Next
For Each oAttach In oItem.Attachments
if right(lcase(oAttach.filena
cTempFile = "\\Public Folders - " +
_user@mydomain.com\Favorit
else
cTempFile = "c:\" + oAttach.FileName
endif
oAttach.SaveAsFile cTempFile
PrintFile cTempFile, cNoPrint
Next
At the moment the code will only pront the attachments of the currently selected email.
You will need to include further code to surround the block of code satarting at lines 12-13, viz:
'obtain pointer to current email message
Set oItem = Application.ActiveInspecto r.CurrentI tem
Instead of "CurrentItem" the object "oItem" would be set to point to each email in a folder. In turn, each folder would be exaqmined.
The logic would be:
For each folder in my Outlook
.....Look at each email item.
For each item (if it has not been read)
.......PrintAttachments()
I would have to do a lot more testing to expamnd this, but I must get off to bed (I have to attend a funeral in about 5 hours!....Not my own, thank goodness!
Will check back later this afternoon.
Goodnight...
Chris
(craisin)
You will need to include further code to surround the block of code satarting at lines 12-13, viz:
'obtain pointer to current email message
Set oItem = Application.ActiveInspecto
Instead of "CurrentItem" the object "oItem" would be set to point to each email in a folder. In turn, each folder would be exaqmined.
The logic would be:
For each folder in my Outlook
.....Look at each email item.
For each item (if it has not been read)
.......PrintAttachments()
I would have to do a lot more testing to expamnd this, but I must get off to bed (I have to attend a funeral in about 5 hours!....Not my own, thank goodness!
Will check back later this afternoon.
Goodnight...
Chris
(craisin)
ASKER
Wow, thanks again, I will test out your suggestions and report back.
Yes, I am in Australia.......(Melbourne )....Off to the funeral now///will be able to do some more work on this later tonight (in about 15 hours time) since I am running a bridge club tonight and need to prepare all the hands etc. this afternoon.
Can work extensively on this tomorrow (Saturday) as well.......looks very promising.
The only problem I have (of course) is that when I test my printer keeps wanting top print heaps of stuff! :-)
Cheers....be back soon.
Chris
(craisin)
Can work extensively on this tomorrow (Saturday) as well.......looks very promising.
The only problem I have (of course) is that when I test my printer keeps wanting top print heaps of stuff! :-)
Cheers....be back soon.
Chris
(craisin)
OK...This is where I am at.
The code below appears to work by scanning all the folders and subfolders.
Rather than PRINT everything during testing, I have a message box popping up saying an item is being printed (simulation) The box shows the filename and also the SUBJECT of the message to which the file is attached.
If you answer "NO" to the message, the macro stops.
If you answer "Yes" it continues (This could take a while if there are a lot of messages with attachments).
Once we are happy it is doing what it should, we can comment out the "ShowMsg" lines and UNComment the actual lines which do the printing within the sub "PrintFile".
Warning: The MsgBox at the end could be VERY big if a lot of files do not print.
We will remove this "Files not printed" message, I think, once we know every thing is running as it should.
Of course you can tweak the code to suit.
I think this code runs through ALL Folders, so if you only want it on the currently selected Folder, the code will need changing (perhaps a seperate version for "Current Folder" as opposed to "All Folders"?)
Give this a code a test and see how you go.
Cheers
Chris
(craisin)
The code below appears to work by scanning all the folders and subfolders.
Rather than PRINT everything during testing, I have a message box popping up saying an item is being printed (simulation) The box shows the filename and also the SUBJECT of the message to which the file is attached.
If you answer "NO" to the message, the macro stops.
If you answer "Yes" it continues (This could take a while if there are a lot of messages with attachments).
Once we are happy it is doing what it should, we can comment out the "ShowMsg" lines and UNComment the actual lines which do the printing within the sub "PrintFile".
Warning: The MsgBox at the end could be VERY big if a lot of files do not print.
We will remove this "Files not printed" message, I think, once we know every thing is running as it should.
Of course you can tweak the code to suit.
I think this code runs through ALL Folders, so if you only want it on the currently selected Folder, the code will need changing (perhaps a seperate version for "Current Folder" as opposed to "All Folders"?)
Give this a code a test and see how you go.
Cheers
Chris
(craisin)
Public Sub PrintAttachments()
'Code to print all attachments to an email
Dim objOutlook As New outlook.Application
Dim objNS As outlook.NameSpace
Dim objFolder As outlook.MAPIFolder
Dim nFolder As Long
Dim objSubFolder As Object
Dim oItems As Object
Dim oItem As outlook.MailItem
Dim oAttach As outlook.Attachment
Dim cTempFile As String
Dim cNoPrint As String
Set objNS = objOutlook.Session
Set objFolder = objNS.Folders.GetFirst
On Error Resume Next 'just in case folder already exists....
Kill "C:\TempPrint\TempZipExtract\*.*"
RmDir "c:\TempPrint\TempZipExtract"
Kill "C:\TempPrint\*.*"
MkDir "C:\TempPrint"
On Error GoTo 0
'Set objFolder = outlook.Session.Folders.Item("Public Folders")
For nFolder = 0 To objFolder.Folders.Count
'Set objFolders = outlook.Session.Folders
For Each objSubFolder In objFolder.Folders
'obtain pointer to current email message
Set oItems = objSubFolder.Items
For Each oItem In oItems
For Each oAttach In oItem.Attachments
cTempFile = "c:\TempPrint\" + oAttach.FileName
On Error GoTo skipprint
oAttach.SaveAsFile cTempFile
PrintFile cTempFile, cNoPrint, oItem
skipprint:
DoEvents
Next
DoEvents
Next
DoEvents
Next
DoEvents
Next
If Len(cNoPrint) > 0 Then
MsgBox "The following files could not be printed:" + vbCrLf + _
"(No file Association or macro cannot yet handle extension)" + vbCrLf + vbCrLf + cNoPrint
End If
On Error Resume Next
Kill "c:\TempPrint\*.*"
End Sub
Private Sub PrintFile(cTempFile As String, ByRef cNoPrint As String, oItem As outlook.MailItem)
Dim i As Integer
Dim s As String
Dim nAt As Integer
Dim cExt As String
Dim cRun As String
Dim nFile As Integer
Dim cLine As String
Dim nRun As Long
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
s = String(MAX_FILENAME_LEN, 32)
'Retrieve the name and handle of the executable, associated with this file
i = FindExecutable(cTempFile, vbNullString, s)
If i > 32 Then
cRun = Left$(s, InStr(s, Chr$(0)) - 1)
nAt = InStrRev(cTempFile, ".")
cExt = Mid(cTempFile, nAt)
Select Case LCase(cExt)
Case ".zip"
cRun = fs.GetparentFoldername(cRun) + "\"
cRun = cRun + "wzunzip.exe " + Chr(34) + cTempFile + Chr(34) + " c:\TempPrint\TempZipExtract"
Shell cRun, vbHide
cTempFile = Dir("C:\TempPrint\TempZipExtract\*.*")
Do While cTempFile <> "" ' Start the loop
PrintFile "c:\TempPrint\TempZipExtract\" + cTempFile, cNoPrint, oItem 'Recursion!
cTempFile = Dir
Loop
Case ".pdf"
ShowMsg "Printing " + cTempFile, oItem
'Shell cRun + "/h /p " + Chr(34) + cTempFile + Chr(34), vbHide
Case ".jpg", ".gif", ".tif"
'do we reaally want to print graphics?
Case ".txt"
ShowMsg "Printing " + cTempFile + " using Notepad", oItem
'Shell "NOTEPAD.EXE /p " + cTempFile, vbHide
Case ".doc", ".docx"
ShowMsg "Printing " + cTempFile, oItem
'put ome code here to send a word document to the printer
Case "html", "htm"
'code to print HTML files should be placed here
Case Else
'I think we should not chance trying to print a file with an
'extension for which we have not specifically allowed.
cNoPrint = cNoPrint + cTempFile
End Select
Else
cNoPrint = cNoPrint + cTempFile
End If
End Sub
Private Sub ShowMsg(cMsg, oItem As outlook.MailItem)
If MsgBox(cMsg + vbCrLf + "(Subject: " + oItem.Subject + ")" + vbCrLf + "Continue?", vbInformation + vbYesNo) = vbNo Then
End
End If
End Sub
ASKER
So with this code, say if I have two emails and both have a pdf attachment with the same name, will this script be able to save both files in the C temp folder and name the other one with a (1) suffix to prevent file name conflicts?
Not a big issue i guess, since I can guide the user to go to the temp file and delete the older file with the same name after it has been printed, but some automation in the task would be nice to prevent user errors.
Not a big issue i guess, since I can guide the user to go to the temp file and delete the older file with the same name after it has been printed, but some automation in the task would be nice to prevent user errors.
ASKER
Also, chris, I have another question about how to auto move items from one folder to another, I'm not sure if you could help me out with that as well?
At line 105 in the "PrintFile" subroutine add the line: "Kill cTempFile". That should delete the temporary file after it has been printed. Then the problem of "duplicated file names" would not be a problem.
If the file cannot be printed in that routine it will then still be deleted (which is what we are after).
Even though you have added that line, I would still leave in the other "Kill" lines in the "PrintAttachments" routine, just to be on the safe side.
As far as the "automove" question goes, are you talking about moving emails from one folder to another as they are received (rather than simply going into the "InBox")? If so, you will have to post it as another question, since it really has no connection with the question of printing attachments. I would be more than happy to he;p out then, but please hold off for about 10 hours though, so I can get some sleep first! :-)
Cheers
Chris
If the file cannot be printed in that routine it will then still be deleted (which is what we are after).
Even though you have added that line, I would still leave in the other "Kill" lines in the "PrintAttachments" routine, just to be on the safe side.
As far as the "automove" question goes, are you talking about moving emails from one folder to another as they are received (rather than simply going into the "InBox")? If so, you will have to post it as another question, since it really has no connection with the question of printing attachments. I would be more than happy to he;p out then, but please hold off for about 10 hours though, so I can get some sleep first! :-)
Cheers
Chris
ASKER
Already posted the question. ID: 27324253
ASKER
well after extensively testing both craisin's script and the script from how to geek posted by ravindran_eee, it seems that i was able to get the latter working very well. I tried to play around with yours, chris, but once the other script starting working to suit our company's needs, i didnt have the time or liberty to continue testing yours.
But, i do want to thank you, chris, for the time you put into the script, it was above and beyond the quality of effort i expected any expert at EE to put in. And certainly your script allowed me to get a bit more acquainted with VB script.
Thanks to both experts for helping me out.
But, i do want to thank you, chris, for the time you put into the script, it was above and beyond the quality of effort i expected any expert at EE to put in. And certainly your script allowed me to get a bit more acquainted with VB script.
Thanks to both experts for helping me out.
ASKER
The script from ravindran eee posted on how to geek worked out exactly as needed.
Check this.. It has a macro that would server your exact purpose! You can get more just by Googling :)