Reply All With Attachments


 

I was checking Twitter for questions about Outlook yesterday when I came across this one from smelibari.

Outlook doesn’t retain attachments on replies, presumably because the reply is going back to the person that sent the attachment(s). Clearly they must already have them or they couldn’t have sent them to you. So, while I’m not sure what the use case is for replying with attachments, the solution is pretty simple. Use a macro to create the reply, then add all the attachments from the original message to the reply. The macro will work with both an open message or a message selected in a folder. Of course the open/selected item must be an email. This solution should work with Outlook 2007 and later.

Instructions.

Follow these instructions to add the code to Outlook.

  1. Start Outlook
  2. Press ALT + F11 to open the Visual Basic Editor
  3. If not already expanded, expand Microsoft Office Outlook Objects
  4. If not already expanded, expand Modules
  5. Select an existing module (e.g. Module1) by double-clicking on it or create a new module by right-clicking Modules and selecting InsertModule.
  6. Copy the code from the code snippet box and paste it into the right-hand pane of Outlook’s VB Editor window
  7. Click the diskette icon on the toolbar to save the changes
  8. Close the VB Editor
Sub ReplyAllWithAttachments()
    Const SCRIPT_NAME = "Reply All With Attachments"
    Dim olkMsg As Object, olkRpl As Outlook.MailItem, olkAtt As Outlook.Attachment, strTmp As String
    Select Case TypeName(Application.ActiveWindow)
        Case "Explorer"
            Set olkMsg = Application.ActiveExplorer.Selection(1)
        Case "Inspector"
            Set olkMsg = Application.ActiveInspector.CurrentItem
        Case Else
            Set olkMsg = Nothing
    End Select
    If olkMsg.Class = olMail Then
        strTmp = Environ("TEMP") & "\"
        Set olkRpl = olkMsg.ReplyAll
        For Each olkAtt In olkMsg.Attachments
            If Not IsHiddenAttachment(olkAtt) Then
                olkAtt.SaveAsFile strTmp & olkAtt.Filename
                olkRpl.Attachments.Add strTmp & olkAtt.Filename
                Kill strTmp & olkAtt.Filename
            End If
        Next
        olkRpl.Display
    Else
        MsgBox "This macro only works with emails.", vbCritical + vbOKOnly, SCRIPT_NAME
    End If
    Set olkMsg = Nothing
    Set olkRpl = Nothing
    Set olkAtt = Nothing
End Sub

Private Function IsHiddenAttachment(olkAtt As Outlook.Attachment) As Boolean
    ' Purpose: Determines if an attachment is a hidden attachment.
    ' Written: 7/12/2012
    ' Author:  David Lee
    ' Outlook: 2007 and later
    Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001E"
    Dim olkPA As Outlook.PropertyAccessor, varTemp As Variant
    On Error Resume Next
    Set olkPA = olkAtt.PropertyAccessor
    varTemp = olkPA.GetProperty(PR_ATTACH_CONTENT_ID)
    IsHiddenAttachment = (varTemp <> "")
    On Error GoTo 0
    Set olkPA = Nothing
End Function

Adding Buttons to Run the Macro with a Single Click.

If smelibari wants to run the macro with a single click, then he’ll need to add a toolbar button in Outlook 2007 or a button on the Quick Access Toolbar (QAT) for Outlook 2010. Here’s how.

  • Outlook 2007. Follow these instructions to add a toolbar button that runs the macro.
  • Outlook 2010. Follow these instructions to add the macro to the QAT.
Advertisements

49 comments on “Reply All With Attachments

  1. Hi Dave,

    I found your reply all script from a couple of years ago. It seems to be working great. I was just wondering if it is possible to already add some predefined text to the reply mail. Preferably in HTML. I have been googling for hours but can not seem to find a solution for this. Hope you can help.

    Kind regards,

    Diego

    • Hi, Diego.

      Yes, that’s possible. Here’s a modified version of the code that does this. Replace the ReplyAllWithAttachments subroutine from the original code with the version below. Leave the rest of the code as is.

      Sub ReplyAllWithAttachments()
          'On the next line, edit the predefined text as needed.  This text will then be added to each reply.
          Const PREDEFINED_TEXT = "Your HTML text goes here."
          Const SCRIPT_NAME = "Reply All With Attachments"
          Dim olkMsg As Object, olkRpl As Outlook.MailItem, olkAtt As Outlook.Attachment, strTmp As String
          Select Case TypeName(Application.ActiveWindow)
              Case "Explorer"
                  Set olkMsg = Application.ActiveExplorer.Selection(1)
              Case "Inspector"
                  Set olkMsg = Application.ActiveInspector.CurrentItem
              Case Else
                  Set olkMsg = Nothing
          End Select
          If olkMsg.Class = olMail Then
              strTmp = Environ("TEMP") & "\"
              Set olkRpl = olkMsg.ReplyAll
              olkRpl.HTMLBody = PREDEFINED_TEXT & olkRpl.HTMLBODY
              For Each olkAtt In olkMsg.Attachments
                  If Not IsHiddenAttachment(olkAtt) Then
                      olkAtt.SaveAsFile strTmp & olkAtt.Filename
                      olkRpl.Attachments.Add strTmp & olkAtt.Filename
                      Kill strTmp & olkAtt.Filename
                  End If
              Next
              olkRpl.Display
          Else
              MsgBox "This macro only works with emails.", vbCritical + vbOKOnly, SCRIPT_NAME
          End If
          Set olkMsg = Nothing
          Set olkRpl = Nothing
          Set olkAtt = Nothing
      End Sub
      
    • Hi Dave, That seems to work. One additional question, is it also possible to add a calculated date to the HTML text? If I add + strDate + to the code it does not calculate the date like it does in my other scripts. Or is this due to the fact that the text is defined as a Const and not HTMLBody? Is there a way to have this included as well?
      Regards,
      Diego

    • Hi, Diego.

      Yes, that’s doable, but not with the approach I took. We need to change from using a constant to using a variable. Something like this

      Sub ReplyAllWithAttachments()
          Const SCRIPT_NAME = "Reply All With Attachments"
          Dim olkMsg As Object, olkRpl As Outlook.MailItem, olkAtt As Outlook.Attachment, strTmp As String, strTxt As String
          'On the next line, edit the predefined text as needed.  This text will then be added to each reply.
          strTxt = "Your HTML goes here.  You can add your date like this " & Date
          Select Case TypeName(Application.ActiveWindow)
              Case "Explorer"
                  Set olkMsg = Application.ActiveExplorer.Selection(1)
              Case "Inspector"
                  Set olkMsg = Application.ActiveInspector.CurrentItem
              Case Else
                  Set olkMsg = Nothing
          End Select
          If olkMsg.Class = olMail Then
              strTmp = Environ("TEMP") & "\"
              Set olkRpl = olkMsg.ReplyAll
              olkRpl.HTMLBody = strTxt & olkRpl.HTMLBODY
              For Each olkAtt In olkMsg.Attachments
                  If Not IsHiddenAttachment(olkAtt) Then
                      olkAtt.SaveAsFile strTmp & olkAtt.Filename
                      olkRpl.Attachments.Add strTmp & olkAtt.Filename
                      Kill strTmp & olkAtt.Filename
                  End If
              Next
              olkRpl.Display
          Else
              MsgBox "This macro only works with emails.", vbCritical + vbOKOnly, SCRIPT_NAME
          End If
          Set olkMsg = Nothing
          Set olkRpl = Nothing
          Set olkAtt = Nothing
      End Sub
      
  2. Hi David,

    The replyall script is working great. Is it also possible to add some predefined text to the reply mail? At the moment it generated a reply where I have to type my own text but I would like to script the initial part of my response.

    Kind regards,

    Diego

  3. Everywhere I read that question, most of the people say the same as you…”the people you want to reply to already have the message” But you all forget, MS gives you the ability to make a change to the attachment, and save it directly in the email….So YES, i would like to send it back as a reply! In my company, I ask for updates from various employees. It would be so much easier if they could just open the attachment, add their update, and resend to me. I wouldn’t have to remind them so often.

    • Hi, DCarr.

      Ok. This is the solution for what you described. If you want the solution to use Reply instead of ReplyAll, then change ReplyAll to Reply on line 14.

    • Hi, Josh.

      Are you getting an error? if so, what does the error say and what line is it occurring on? If you aren’t getting an error, then are you sure that the macros are running at all?

      Thanks! I’m glad you like the blog.

    • With the Reply all with Attachments script, I receive the following error:

      Compile Error: Syntax Error

      The function (ReplyAllWithAttachments) is yellow and the following lines are red:

      If olkMsg.Class = olMail Then
      &
      olkRpl.Attachments.Add strTmp & olkAtt.Filename

      With the username script (http://deployhappiness.com/using-outlook-macros-work-smarter/?utm_source=feedburner&utm_medium=email&utm_campaign=Feed%3A+Deployhappiness+%28DeployHappiness%29) I receive the following error:

      Compile Error: Syntax Error

      This line is yellow:

      Function GetUsernameFromAlias(strAls As String) As String

      These are red:

      strSrc = “‘LDAP://” & strDNC & “‘”
      &
      Set adoRec = adoCon.Execute(“SELECT samAccountName FROM ” & strSrc & ” Where objectClass=’user’ AND objectCategory=’Person’ AND mailNickname='” & strAls & “‘”)

      With this script, the process just stops working when i receive a new email….

      Thank you for your help!

    • I’m running Outlook 2013 and i’m running the macro as described:

      Macro (Reply all with Attachments)
      -Added the Macro
      -Trust Center Settings – selected “Notifications for all Macros”
      -Added a new tab, with the macro there
      -Then receive error when trying to use it

      Macro (Showing Active Directory Username in Outlook)
      -Added Macro
      -Trust Center Settings – selected “Notifications for all Macros”
      -Receive email, then the error happens.

    • For the reply all macro, I have it selected within my inbox and then run the macro. Once i do that it gives me the error.

      For the other one, since it’s enabled, it triggers every time I receive a new email from within our network.

  4. Hello Dave,

    Thanks for the code. I have to reply to all and edit the attachment frequently, so this is what I needed.

    However the original code I copied was eliminating all attachments as hidden. I couldn’t debug why so I just commented out the If/Endif.

    Thanks again,
    Rick

    • Microsoft Office Professional Plus 2010
      ver 14.0.6023.1000

      (varTemp “”) always evaluates to TRUE

      I created the macro yesterday and today Outlook thinks it is a security risk and won’t run it. I’ll have to figure that out later. My VB skill level is just barely above script kitty.

    • Rick,

      Could you share one of these messages with me so I can try to find out why the code is seeing the item as a hidden attachment?

    • HI
      I have the same problem, all attachments aren’t in the reply. I’m using Office 365 ProPLus, 15.0.4623.1003. Without IsHiddenAttachment all attachments are in the reply, but the hidden ones are also there.

      Can you help David Lee?

    • Hi, Frank.

      Office 365 Pro Plus is essentially Office 2013. My Office 2013 computer died and I haven’t set up a new one yet, so I can’t test the code with that version. I did test it again on a computer with Office 2010 and it worked properly.

      I’ve added some code to the IsHiddenAttachment function to try and determine what is happening. Please replace the IsHiddenAttachment function with the version below. Once you’ve done that, please select a message containing at least one hidden and one non-hidden attachment and run the macro. The code will display a dialog-box for each attachment in the message. The dialog-box will either report an error or some information about that attachment. Please report that information to me.

      Private Function IsHiddenAttachment(olkAtt As Outlook.Attachment) As Boolean
          ' Purpose: Determines if an attachment is a hidden attachment.
          ' Written: 7/12/2012
          ' Author:  David Lee
          ' Outlook: 2007 and later
          Const PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001E"
          Dim olkPA As Outlook.PropertyAccessor, varTemp As Variant
          On Error Resume Next
          Set olkPA = olkAtt.PropertyAccessor
          varTemp = olkPA.GetProperty(PR_ATTACH_CONTENT_ID)
          If Err.Number <> 0 Then
              MsgBox "Error " & Err.Number & vbCrLf & Err.Description, vbCritical + vbOkOnly, "Is Hidden Attachment"
          Else
              MsgBox "Attachment: " & olkAtt.Filename & vbCrLf & "varTemp: " & varTemp, vbInformation + vbOkOnly, "Is Hidden Attachment"
          End If
          IsHiddenAttachment = (varTemp <> "")
          On Error GoTo 0
          Set olkPA = Nothing
      End Function
      
    • I’ve put the whole code in Modules\Module1 (not in ThisOutlookSession). I’ve also added new button on the ribbon with that macro.
      Dialog-boxes:
      – Att.: ATT0001.gif
      varTemp: _1_0D43EEE40D43EC780001F8516C1257E2A
      – Att.: image001.png
      varTemp: image0001.png@01D078E2.E19477D0

      I think ATT0001.gif is a picture on mail (not the attachment),
      image001.png and test.pdf are attachments.

    • Frank,

      According to that output, all three of those files are hidden attachments. Normal, non-hidden, attachments should result in varTemp being blank. Could you share that message with me? If you can, then I’ll send you an email and you can send a reply back with that message attached to it. It’s important to attach the message. Copying and pasting, forwarding the message, or sending a screenshot won’t work. I need the actual, unaltered, message itself so I can look at its properties.

    • If you can see my e-mail adress then you can send an email to me, and I will repely with zipped test message attached. If that won’t be enough I will try to make another message and I will send it to you.

    • So I’ve tested the macro on other e-mails and sometimes it works and sometimes it doesn’t work. I can’t figure out why it only works on some e-mails.

    • I don’t know if all of them are in HTML, but at least one is in HTML format and macro doesn’t work on it.

    • I’ve made some tests using OutlookSpy.
      On the ribbon OutlookSpy tab, option IMessage, GetAttachmntTable tab.
      Macro works when PR_ATTACH_MIME_TAG_W has value MAPI_E_NOT_FOUND.
      Macro doesn’t work when PR_ATTACH_MIME_TAG_W
      has value for example application/octet-stream (but it should be MAPI_E_NOT_FOUND for Word document).

      I hope this helps.

    • Hi, Frank.

      I reloaded Office 2013 and tested the code against the message you provided. It worked perfectly. The reply it created included the Word document but not the graphic in the body.

    • I don’t know why some mesages have PR_ATTACH_MIME_TAG_W set to MAPI_E_NOT_FOUND and some don’t. The macro would work if all the messages had proper PR_ATTACH_MIME_TAG_W value.
      I’ve looked at the code from https://replyallwithattach.codeplex.com/releases/view/30656 and he’s using “forward” to include attachments and copy recipients and mail subject.
      Could you write similar macro that forwards the message and copies only the sender (similar to Reply) and copies all – sender and recipients (similar to Reply All)
      including RE: in teh subject?

    • Hi, Frank.

      I can, but I see that as a workaround rather than a fix. I would prefer to discover why the code performs properly here on my computer but fails on yours, even when we process the same messages. A message’s properties are encapsulated in the message object. In other words, a message’s properties don’t change when the message is moved from one system to the other. We’re both running the same code, and running it using the same version of Office. The mystery is how the code can return one result on your computer and a different one on mine? That doesn’t make sense.

    • I will send you later new msg file for testing, that doesn’t work. As long as a workaround works for every e-mail I’m OK with that kind of soulution.

  5. This is one of those functions which in theory shouldn’t be needed but I’ve wanted this function for years! So thanks a lot for the code.
    Feedback:
    Sub name reads ‘Rely’ not ‘Reply’.
    The const line is missing an “=”.
    I had some trouble cutting and pasting – no line wrap on pasting to VBA editor or text editor, it worked in the end into Word.
    I also had problems with this ‘Leave a Reply’ box in IE9. It worked when I switched to Chrome.
    Thanks again.
    Dave811

    • Hi, Dave.

      You’re welcome. I’m glad it meets a need you had.

      Thanks for pointing out the typos. I’ve fixed them.

      I’ll check into the cutting/pasting issue.

      There’s nothing I can do about the problem you experienced with “Leave a Reply” in IE9. Site behavior is controlled by the folks at WordPress.

      Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s