I initially started using IMAP through outlook with version 2003. If you've used it for IMAP, or attempted to, then I'm sure you've felt my pain. Outlook 2007 should have been the fix for their terrible IMAP implementation, but alas, it was not.
I spent some time digging around online to find a way to make Outlook handle deleting emails a little more appropriately for an IMAP account. Most of the solutions involved incorporating a macro into the toolbar and from there having to highlight the emails to be 'deleted' and clicking an additional button. (see this and this) This solution was not acceptable since an untrained user will not know to do this. I needed something better.
I've never specifically written any VBA previously, but I have used Visual Basic frequently in the past, so I figured I would at least have an understanding of the language. I spent some time digging around the MSDN for object reference and getting myself familiar with inspectors and explorers.
I ended up adding inspectors to almost everything and watching as the events fired. At first it seemed like the MailItem's 'BeforeDelete' was my answer, but that only handled emails that you opened in it's own window and not any other time. What I ended up discovering is that a folder would fire the 'BeforeItemMove' even when an item was deleted, whether it was with the delete key or the toolbar button. The difference is that the MoveTo would be Nothing, instead of a destination folder. By trapping this event and passing it with my own function, the deleted emails can be moved to a trash folder of my own specification.
Of course the downside of this is that Outlook simply marks messages for deletion and shows them with a strikethrough. There are a few ways this can be handled. I've chosen to simply have outlook hide the items marked for deletion, and the folders auto-purge when changing (defined in the account settings). This meets all of my needs and is transparent to the user.
So basically this is what the code does: When you start Outlook, the script will create references so that it can watch as events happen. When you do something that would cause an item to be deleted (press delete, click the X on the toolbar) it will check to see if we have a folder named 'Trash' under the root folder, and if so, it will move the email to that folder.
Update February 7th, 2010: Received several emails of people having problems using the specified code, changed code to look for folder named "Deleted Items" which is the default Outlook trash folder name. Was previously using IMAP Trash default.
Update June 1st, 2009: Added check for Trash folder items so you can actually delete something that's in the trash
Outlook will need to be restarted after adding this code
To use this code, copy and paste it into 'ThisOutlookSession' in the VBA editor. (Tools/Macro/Visual Basic Editor) See the screenshots below for help.
You can either copy/paste this code or download outlookimapfix.txt
Public WithEvents myItem As MailItem 'for trapping deletion of opened mail
Public WithEvents myInspector As Inspectors 'for trapping new windows
Public WithEvents myExplorer As Explorer 'for folder reference
Public WithEvents myFolder As Folder 'for trapping mail deletion in main outlook window
Public myNameSpace As NameSpace 'Parent folder
Private Sub Application_Startup()
Set myInspector = Application.Inspectors
Set myExplorer = Application.ActiveExplorer
Set myFolder = myExplorer.CurrentFolder
Set myNameSpace = Application.GetNamespace("MAPI")
End Sub
Private Sub myExplorer_BeforeFolderSwitch(ByVal NewFolder As Object, Cancel As Boolean)
Set myFolder = NewFolder
End Sub
Private Sub myFolder_BeforeItemMove(ByVal item As Object, ByVal MoveTo As MAPIFolder, Cancel As Boolean)
If TypeName(item) = "MailItem" Then 'only trap mail items
Dim lMI As MailItem
Set lMI = item
If MoveTo Is Nothing And lMI.Parent <> "Deleted Items" Then 'Item was deleted
moveIMAPItem lMI
Cancel = True 'bypass normal deletion function
End If
End If
End Sub
Private Sub myInspector_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then Set myItem = Inspector.CurrentItem 'New window for reading mail
End Sub
Private Sub myItem_BeforeDelete(ByVal item As Object, Cancel As Boolean)
If TypeName(myItem) = "MailItem" Then 'only trap mail items
moveIMAPItem item
Cancel = True 'bypass normal deletion
End If
End Sub
Private Sub moveIMAPItem(ByVal item As Object)
Dim lMI As MailItem
Dim fParent As Folder
Dim parentFolder As Folder
Dim trashFolder As Folder
Set lMI = item
Set fParent = myExplorer.CurrentFolder
Do Until fParent.Parent = myNameSpace 'Root folder
Set fParent = fParent.Parent
Loop
Set parentFolder = fParent
If parentFolder.Folders("Deleted Items") Is Nothing Then 'Deleted Items folder doesn't exist
MsgBox "Unable to find folder named 'Deleted Items'", vbOKOnly + vbInformation, "IMAP Delete" 'Inform user and exit routine
Exit Sub
End If
Set trashFolder = parentFolder.Folders("Deleted Items") 'Set destination
lMI.Move trashFolder 'move email
End Sub