Outlook: Decline Meeting Invite but Save a Copy

Outlook doesn’t offer a built-in feature to decline a meeting invitation whilst keeping a copy of the meeting in your calendar. In this blog post I’ll explain how to add this in.

Why is this even useful though? Sometimes I get invited to a meeting that I can’t / won’t attend but want to keep the attached papers for, or at least a record of when the meeting took place and who was invited. I’d like to let the organiser know that I’ve received their invitation but won’t be attending, however Outlook’s “Decline” response auto-deletes the invitation and appointment – so I’ve lost all that good information. Alas there’s no option to change the behaviour of “Decline”.

What I want is a button I can click (from the meeting invitation email) that will send a “decline” response back to the organiser, keep (a copy of) the meeting in my calendar, and mark the appointment as “Free”.

This is actually pretty easy in Outlook 2013, and I’ve drawn on some neat code to accept or decline a meeting request using VBA from Diane Pomersky at Slipstick, and a handy sub-routine to copy attachments on Outlook items from Sue Mosher.

Here’s the VBA code you need to add:

Public Sub SaveAndDecline()
    Dim oAppt As AppointmentItem
    Dim cAppt As AppointmentItem
    Dim oResponse

    Set cAppt = GetCurrentItem.GetAssociatedAppointment(True)
    Set oAppt = Application.CreateItem(olAppointmentItem)

    With oAppt
        .Subject = "DECLINED: " & cAppt.Subject
        .Location = cAppt.Location
        .Body = cAppt.Body
        .Categories = cAppt.Categories
        .Importance = cAppt.Importance
        .Start = cAppt.Start
        .Duration = cAppt.Duration
        .BusyStatus = olFree
        .RequiredAttendees = cAppt.RequiredAttendees
        .OptionalAttendees = cAppt.OptionalAttendees
        .Resources = cAppt.Resources
        .ReminderSet = cAppt.ReminderSet
        .ReminderMinutesBeforeStart = cAppt.ReminderMinutesBeforeStart
        .ResponseRequested = cAppt.ResponseRequested
        .AllDayEvent = cAppt.AllDayEvent
        Call CopyAttachments(cAppt, oAppt)
    End With

    Set oResponse = cAppt.Respond(olMeetingDeclined, True)

    Set cAppt = Nothing
    Set oAppt = Nothing
End Sub

Function GetCurrentItem() As Object
    Dim objApp As Outlook.Application
    Set objApp = Application
    On Error Resume Next
    Select Case TypeName(objApp.ActiveWindow)
    Case "Explorer"
    Set GetCurrentItem = objApp.ActiveExplorer.Selection.Item(1)
    Case "Inspector"
    Set GetCurrentItem = objApp.ActiveInspector.CurrentItem
    End Select
    Set objApp = Nothing
End Function

Sub CopyAttachments(objSourceItem, objTargetItem)
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set fldTemp = fso.GetSpecialFolder(2) ' TemporaryFolder
    strPath = fldTemp.Path & "\"

    For Each objAtt In objSourceItem.Attachments
        strFile = strPath & "outlook_att_copy-" & objAtt.FileName
        objAtt.SaveAsFile strFile
        objTargetItem.Attachments.Add strFile, , , objAtt.DisplayName
        fso.DeleteFile strFile

    Set fldTemp = Nothing
    Set fso = Nothing
End Sub

Notice that I’ve copied quite a few more properties of the appointment over – setting the Free/Busy status to Free on the way.

Once you’ve added this to a VBA module in Outlook you can associated it with a button on the Main / Home ribbon for easy access when reading email.