'Delete a mailitem permanently in outlook
I'm trying to delete a mailitem using the outlook API. Like the following,
Dim objMail
For each objMail in objFolder.Items
objMail.Delete
Next
Obviously, deleting an item straight away is to simple. Outlook just move it into the "Deleted Items" folder instead of deleting it. I tried to get the "Deleted Items" folder using
OutlookNameSpace.GetDefaultFolder(olDeletedItems)
and delete the mail again, but the PST the code is working on is not the default mailbox and the folder returned is the wrong deleted items folder. How can I permanently delete this mailitem?
I tried to loop through all folders in the current store, but there's no way of telling which folder is the deleted items folder except by comparing names, I can't do that since the programs will be used in multiple languages and the name is different for each version.
PS: I cannot use a third party dll :(
Help!
Solution 1:[1]
First problem of your code is not appropriate loop you use. If you want to delete (almost anything in VBA) you need to loop your collection from the last element to first. If not, you change the order of the collection- after you delete 1st element >> 2nd one is moved to 1st position and will not be deleted.
Therefore this code should delete all items from your DeltetedItems folder
:
Sub Delete_all_from_dust_bin()
Dim myFolder As Outlook.Folder
Set myFolder = Application.GetNamespace("MAPI"). _
GetDefaultFolder(olFolderDeletedItems)
Dim i As Long
For i = myFolder.items.Count To 1 Step -1
myFolder.items(i).Delete
Next i
End Sub
Obviously, you could prepare similar code for deleting from any other folder. You will run both deletion loops to remove items for sure.
Some additional remarks for MailItem.Delete Method
from MSDN:
The Delete mothod deletes a single item in a collection. To delete all items in the Items collection of a folder, you must delete each item starting with the last item in the folder. For example, in the items collection of a folder, AllItems, if there are n number of items in the folder, start deleting the item at AllItems.Item(n), decrementing the index each time until you delete AllItems.Item(1).
Edit due to some comments from OP.
Even if you need to delete some items (not all) remember to use the loop type I presented above.
If you need to refer to any other DeletedItems folder
in other stores you can find this folder in these ways:
'with index reference
Application.GetNamespace("MAPI").Stores(2).getdefaultfolder(olFolderDeletedItems)
'with name reference
Application.GetNamespace("MAPI").Stores("Business Mail").getdefaultfolder(olFolderDeletedItems)
I don't know if this works with all Outlook versions but it's working with Outlook 2010.
Solution 2:[2]
For reference purpose, here's the final method to permanently delete an item I found.
PS: The Migration ID is GUID previously stored for a bulletproof-way to track the item
Dim mailIndex
For mailIndex = objFolder.Items.Count To 1 Step - 1
Dim migrationProperty
Set migrationProperty = GetMigrationProperty(objFolder.Items(mailIndex).ItemProperties
if not migrationProperty is nothing Then
objFolder.Items(mailIndex).Delete
Call DeleteMailPermanently(migrationProperty.Value)
End if
Next
Function DeleteMailPermanently(strMailMigrationID)
Dim objDeletedMail, objDeletedMigrationProperty
Set m_objPSTDeletedItemsFolder
= GetDeletedItemsFolder(PSTStore, strMailMigrationID)
For Each objDeletedMail in m_objPSTDeletedItemsFolder.Items
Set objDeletedMigrationProperty
= GetMigrationProperty(objDeletedmail.ItemProperties)
if not objDeletedMigrationProperty is nothing
and objDeletedMigrationProperty.Value = strMailMigrationID then
objDeletedMail.Delete
Next
End Function
Function GetDeletedItemsFolder(objParentFolder, strMigrationID)
Dim objFolder, objMail
For each objMail in objFolder.Items
Dim migrationProperty
Set migrationProperty = GetMigrationProperty(objMail.ItemProperties)
If migrationProperty.Value = strMigrationID
Set GetDeletedItemsFolder = objFolder
Exit Function
End If
Next
if objFolder.Folders.Count >= 1 Then
Dim subFolder
Set subFolder = GetDeletedItemsFolder(objFolder, strMigrationID)
If not subFolder is Nothing Then
Set GetDeletedItemsFolder = subFolder
Exit Function
End If
Set GetDeletedItemsFolder = Nothing
End function
Solution 3:[3]
I had the same problem - my code wanted to delete appointment items as part of a sync, but this was clogging up the Deleted Items folder. But what I realised was - when you delete an object, all it's doing is moving it to Deleted Items. So just delete it twice! No need to worry about tracking properties, or clearing out the whole folder (which may be overkill).
EDIT: no, sorry, this doesn't work. Stupid Outlook. I tried using the Move method, and then deleting from Deleted Items, but it just puts it in the Drafts folder instead, bizarrely.
What seems to work is deleting an item, then deleting the last item in Deleted Items.
Here's a fragment of my code:
Set ns = Application.GetNamespace("MAPI")
Set delItemsFolder = ns.GetDefaultFolder(olFolderDeletedItems)
Set calItems = syncFolder.Items
For i = calItems.Count To 1 Step -1
calItems(i).Delete
delItemsFolder.Items.Item(delItemsFolder.Items.Count).Delete
Next
Solution 4:[4]
Also, if you need the Deleted Items folder from a store other than the default store. use Store.GetDefaultFolder
instead of Namespace.GetDefaultFolder
.
If you want to completely bypass the Deleted Items folder, you will need to either use Extended MAPI (C++ or Delphi only - IMAPIFolder::DeleteMessages) or Redemption (I am its author - any language - its RDOMail.Delete
method allows to either permanently delete the message or move it to the Deleted Items folder).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Machinegon |
Solution 3 | |
Solution 4 |