Welcome to Office Zealot Sign in | Join | Help

A Better Way To View Multiple Picture Attachments

NOTE:
Due to data loss with OfficeZealot's blog server, all comments posted between April 28 and June 8, 2005  to any of my blog entries were inadvertently deleted.  The end of this blog entry contains the text of the comments applicable to this posting that I was able to recover.

ANOTHER UPDATE:  The content of this article is superceded by a newer version with more features, outlined in this article on MSDN:

Office Developer Center: Viewing Multiple Picture Attachments in Outlook 2003:
http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/odc_ol2003_ta/html/Office_Outlook_ViewMultPictAttach.asp

UPDATE: The information in this post is really intended for those of you who have some decent experience programming within the Outlook VBA Editor.  I never meant for this to be consumed by general users, so if you don't know how to set references to Type Libraries, create User Forms or compile and debug VBA, then you know you are not the intended audience.  I may redo this solution as a downloadable, installable COM Add-In sometime - for use by ALL Outlook users - so stay tuned...

This is one of my most heavily used weapons in my Outlook macro arsenal, and saves me a lot of grief. Take a look at the screenshot below:

Message Attachments Screenshot

Doesn't this drive you nuts? You can select all of the attachments in an e-mail, but you can't launch all of them at the same time. You have to double-click each one individually. I'm sure there's been many times when you've received an e-mail from one of your friends with 15 joke pictures, or Aunt Rose sends you 5 photos of her new cat, and it quickly becomes a real chore to open - view - close every single attachment.

Read on, and I'll show you the code for a much better way to handle this.

The Message Attachments Form

Ultimately, this is what you will see when you click a custom button on one of your toolbars:

 Custom Form Screenshot

This form will contain a list of all the picture attachments in the current message (those with .gif, .jpg, .tif or .bmp extensions; you can enter additional ones in the frmAttachments.FillList procedure). You can selectively choose non-contiguous entries in the list with Shift-clicks, all entries, just one attachment (double-clicks are enabled), and then click a button to show the picture(s).

Launching the Message Attachments Form

First off, to launch this form, create this macro and put it either in your ThisOutlookSession module or any Modules you have in your VBA Project:

Sub ViewAttachments()
On Error GoTo EH:

    Dim objMessage As Object

    Set objMessage = Application.ActiveInspector
    If objMessage.CurrentItem.Attachments.Count = 0 Then Exit Sub
    Set frmAttachments.objMessage = objMessage.CurrentItem
    frmAttachments.FillList
    frmAttachments.Show

EH:
    If Err.Number <> 0 Then
        MsgBox "Something is wrong!"
        Exit Sub
    End If
End Sub

You'll also need to create a custom button on one of your message Toolbars. To do this, choose Customize from the Toolbars sub-menu under the View menu of your message. Click the Commands tab, choose Macros from the Categories list, and select OutlookVBA.ViewAttachments. Now drag that to a spot on any of your Toolbars and you're good to go.

Message Attachments Form Code

Here is the code for the frmAttachments UserForm. Rather than recreating the UserForm yourself, you can download the file to save yourself some trouble. I'll include the code here for reference anyway:

Option Explicit
Public objMessage As MailItem
Dim objFs As New Scripting.FileSystemObject
Dim objTempFolder As Scripting.Folder
Dim strTempFolderPath As String
Dim strTempFilesUsed() As String
Dim lngTempFileCount As Long
Const ImageViewerFilePath As String = """C:\Program Files\Internet Explorer\iexplore.exe """
'ALTERNATELY, IF YOU HAVE Office XP's Photo Editor INSTALLED, USE THAT AS IT IS FAST AND SUPPORTS
'MULTIPLE IMAGE WINDOWS; LOOK FOR C:\Program Files\Common Files\Microsoft Shared\PhotoEd\PHOTOED.EXE
'OR YOU CAN USE WHATEVER IMAGE VIEWER YOU WANT, AS LONG AS IT CAN TAKE ONE FILE NAME AS AN ARGUMENT
'FROM THE COMMAND LINE OR RUN DIALOG

Sub FillList()
    'PRE-POPULATE THE LIST BOX WITH PICTURE ATTACHMENT FILE NAMES
    Dim objAtt As Attachment, objAtts As Attachments
 
    Set objAtts = objMessage.Attachments
    lstAtts.Clear
    For Each objAtt In objAtts
        Select Case Right(objAtt.FileName, 3)
            Case "jpg", "gif", "tif", "bmp", "JPG", "GIF", "TIF", "BMP"
                Me.lstAtts.AddItem objAtt.Index
                Me.lstAtts.List(lstAtts.ListCount - 1, 1) = objAtt.FileName
        End Select
    Next
End Sub

Private Sub cmdClose_Click()
    Unload Me
End Sub

Private Sub cmdOpen_Click()
On Error GoTo EH:

    Dim strFileName As String
    Dim intX As Integer, varRet As Variant

    If lstAtts.ListIndex = -1 Then Exit Sub

    'LOOP THROUGH SELECTED PICTURE ATTACHMENTS
    For intX = 0 To lstAtts.ListCount - 1
        If lstAtts.Selected(intX) = True Then
            strFileName = strTempFolderPath & "\" & objMessage.Attachments.Item(lstAtts.List(intX, 0)).DisplayName
            objMessage.Attachments.Item(lstAtts.List(intX, 0)).SaveAsFile strFileName
            ReDim Preserve strTempFilesUsed(lngTempFileCount)
            strTempFilesUsed(lngTempFileCount) = strFileName
            lngTempFileCount = lngTempFileCount + 1                       

            'LAUNCH IMAGES IN DEFINED IMAGE VIEWER
            varRet = Shell(ImageViewerFilePath & " " & """" & strFileName & """", 1)
        End If
    Next

EH:
    If Err.Number <> 0 Then
        MsgBox Err.Number & vbCrLf & Err.Description & vbCrLf & vbCrLf & "[error in cmdOpen_Click]", vbOKOnly + vbExclamation, "ERROR"
        Exit Sub
    End If
End Sub

Private Sub cmdOpenAll_Click()
On Error GoTo EH:

    Dim strFileName As String
    Dim intX As Integer, varRet As Variant

    If Me.lstAtts.ListCount <= 0 Then Exit Sub

    'LOOP THROUGH ALL PICTURE ATTACHMENTS
    For intX = 0 To lstAtts.ListCount - 1
        strFileName = strTempFolderPath & "\" & objMessage.Attachments.Item(lstAtts.List(intX, 0)).DisplayName
        objMessage.Attachments.Item(lstAtts.List(intX, 0)).SaveAsFile strFileName
        ReDim Preserve strTempFilesUsed(lngTempFileCount)
        strTempFilesUsed(lngTempFileCount) = strFileName
        lngTempFileCount = lngTempFileCount + 1

        'LAUNCH IMAGES IN DEFINED IMAGE VIEWER
        varRet = Shell(ImageViewerFilePath & " " & """" & strFileName & """", 1)
    Next

EH:
    If Err.Number <> 0 Then
        MsgBox Err.Number & vbCrLf & Err.Description & vbCrLf & vbCrLf & "[error in cmdOpenAll_Click]", vbOKOnly + vbExclamation, "ERROR"
        Exit Sub
    End If
End Sub

Private Sub lstAtts_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    cmdOpen_Click
End Sub

Private Sub UserForm_Activate()
    GetTempFolder
End Sub

Private Sub UserForm_Terminate()
    DeleteTempFiles
    Set objMessage = Nothing
    Set objFs = Nothing
    Set objTempFolder = Nothing
End Sub

Sub DeleteTempFiles()
On Error GoTo EH:

    Dim objFile As Scripting.File
    Dim intX As Integer   

    For intX = 0 To UBound(strTempFilesUsed)
        Set objFile = objFs.GetFile(strTempFilesUsed(intX))
        objFile.Delete True
    Next

EH:
    If Err.Number <> 0 Then
        If Err.Number = 9 Then Exit Sub 'strTempFilesUsed ARRAY IS EMPTY; NO FILES WERE OPENED
        If Err.Number = 53 Then Resume Next 'FILE NOT FOUND; MAY HAVE GOT DELETED ALREADY IF THE SAME FILE WAS
        'OPENED MORE THAN ONCE, AS THE FILE NAME WOULD HAVE BEEN DUPLICATED IN THE ARRAY WE ARE PARSING
        MsgBox Err.Number & vbCrLf & Err.Description & vbCrLf & vbCrLf & "[error in DeleteTempFiles]", vbOKOnly + vbExclamation, "ERROR"
        Exit Sub
    End If
End Sub

Sub GetTempFolder()
On Error Resume Next

    Dim objTempFolder As Scripting.Folder   

    'GET THE TEMP FOLDER
    Set objTempFolder = objFs.GetSpecialFolder(2) 'path is found in the TMP environment variable
    If objFs.FolderExists(objTempFolder & "\AttachmentsTemp") = False Then
        Set objTempFolder = objFs.CreateFolder(objTempFolder & "\AttachmentsTemp")
    Else
        Set objTempFolder = objFs.GetFolder(objTempFolder & "\AttachmentsTemp")
    End If
    If Err.Number <> 0 Then
        'UNABLE TO RETRIEVE TEMP FOLDER
        'YOU MAY WANT TO HARDCODE A FOLDER HERE THAT WILL WORK ON YOUR SYSTEM
        strTempFolderPath = "C:\Temp"
 
        If objFs.FolderExists(strTempFolderPath) = False Then
            objFs.CreateFolder strTempFolderPath
        End If

        Set objTempFolder = objFs.GetFolder(strTempFolderPath)
    Else
        strTempFolderPath = objTempFolder.Path
    End If

End Sub

Final Comments

You might notice that I'm using Internet Explorer to launch the images. I can't assume what you are using as the default image viewer on your PC, but IE is always there (!) so I chose that. Feel free to change the viewer to whatever you like. See the inline comments in the code for more information. Have fun using this! I hope it makes your life easier when working with multiple picture attachments.

----------------------------------------------------------------
COMMENTS RESTORED FROM BACKUP:


Sun 6/5/2005 11:40 PM Jimmy

"Hi Eric .. I get a compilation error for the line "objFs As New Scripting.FileSystemObject". It says "User defined type not defined". Please help!

Jimmy"

Mon 6/6/2005 1:15 AM Jimmy

""90
Object variable or with block variable not set

[error in cmdOpen_Click]
"
This is the error I got while trying to open any picture attachment. Anyone got that problem?"


Mon 6/6/2005 6:50 PM Jimmy

"Thanks for that Mate, now I got this runtime error
"91
Object variable or with block variable not set

[error in cmdOpen_Click]
"
This is the error I got while trying to open any picture attachment. Anyone got that problem? "

END COMMENTS RESTORE
----------------------------------------------------------------

Published Thursday, January 29, 2004 12:20 PM by legault
Filed under: ,

Comments

Anonymous comments are disabled