Outlook: rules or macro for an IMAP folder, without hanging application - spam

I have Outlook 2003 at work and have a local Exchange account and a personal account that I access via IMAP.

I get a LOT of spam to my personal account.  I tried setting up rules to delete the spam (flagged by Spam Assassin in the subject line) before even downloading it, but the combination of crappy outlook and my crappy hosting company means that the following occurs:
   Outlook tries to delete the messages from the server, and there is a huge delay in doing so.
   Outlook hangs
   Outlook finally comes back and tells me there was an error in applying one of the rules.

This is unacceptable so I have turned off the rule and let the spam come down to me and delete it manually.

My question is: How to I prevent the spam getting downloaded without Outlook hanging?

Perhaps there is a way to write a macro that can:
   Change to my personal folder inbox
   Search for all items that have "**SPAM" in the subject
   Delete them

Or maybe there is a way of removing them from the server before they even get downloaded?

I realise I could use POP to collect the mail but I do not want to as I check the mail in two different locations and I want to use IMAP to ensure they are synched.

Please advise


Who is Participating?
David LeeConnect With a Mentor Commented:
I'm not going to hold my breath until M$ fixes their products.  I don't look good in blue.

Ok, here's the code for doing this.  follow these instructions to use it:

1.  Start Outlook
2.  Click Tools->Macro->Visual Basic Editor
3.  If not already expanded, expand Microsoft Office Outlook Objects and click on ThisOutlookSession
4.  Copy the code below and paste it into the right-hand pane of the VB Editor window
5.  Click the diskette icon on the toolbar to save the changes
6.  Close the VB Editor
7.  Click Tools->Macro->Security
8.  Set the Security Level to Medium.  
9.  Close Outlook
10.  Start Outlook
11.  Outlook will display a dialog-box warning that ThisOutlookSession contains macros and asking if you want to allow them to run.  Say yes.

You're ready to go.  The messages with "**SPAM" in the subject should be dumped into Deleted Items as they arrive.  

Private WithEvents olkFolder As Outlook.Items

Private Sub Application_Startup()
    'Replace "My Personal Folder Name" with the name of your personal folder
    'Replace "Inbox" with the name of a folder within that personal folder if it's not called Inbox
    Set olkFolder = OpenMAPIFolder("\My Personal Folder Name\Inbox").Items
End Sub

Private Sub Application_Quit()
    Set olkFolder = Nothing
End Sub

Private Sub olkFolder_ItemAdd(ByVal Item As Object)
    'Replace "**SPAM" with the exact wording you want to key on if it doesn't appear exactly as **SPAM
    'If you do replace that litteral text, then remember to adjust the length (6) to match
    If Left(Item.Subject, 6) = "**SPAM" Then
    End If
End Sub

'Credit where credit is due.
'The code below is not mine (well, a little of it is).  I found it somewhere on the
'internet but do not remember where or who the author is.  The original author(s)
'deserves all the credit for these functions.
Function OpenMAPIFolder(ByVal szPath As String)
    Dim app, ns, flr As MAPIFolder, szDir, i
    On Error GoTo errOMF
    Set flr = Nothing
    Set app = CreateObject("Outlook.Application")
    If Left(szPath, Len("\")) = "\" Then
        szPath = Mid(szPath, Len("\") + 1)
        Set flr = app.ActiveExplorer.CurrentFolder
    End If
    While szPath <> ""
        i = InStr(szPath, "\")
        If i Then
            szDir = Left(szPath, i - 1)
            szPath = Mid(szPath, i + Len("\"))
            szDir = szPath
            szPath = ""
        End If
        If IsNothing(flr) Then
            Set ns = app.GetNamespace("MAPI")
            Set flr = ns.Folders(szDir)
            Set flr = flr.Folders(szDir)
        End If
    Set OpenMAPIFolder = flr
    On Error GoTo 0
    Exit Function
    Set OpenMAPIFolder = Nothing
    On Error GoTo 0
End Function

Function IsNothing(Obj)
  If TypeName(Obj) = "Nothing" Then
    IsNothing = True
    IsNothing = False
  End If
End Function

David LeeCommented:
Hi dc197,

> Perhaps there is a way to write a macro that can:
>    Change to my personal folder inbox
>    Search for all items that have "**SPAM" in the subject
>    Delete them

If indeed the messages all have "**SPAM" in the subject, then such a macro is a piece of cake.  The only question would be do I have the macro look for "**SPAM" anywhere in the subject line, or only if it's the first 6 characters?

dc197Author Commented:
It will always be at the start.  But remember it must only apply this rule to my personal folder, not my default Outlook folder.

It must also not hang otherwise I might as well stick with the old solution!

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

David LeeCommented:

> But remember it must only apply this rule to my personal folder, not
> my default Outlook folder.
You'll be in control of that.  It'll run against whatever folder you to tell it to.

> It must also not hang
I wouldn't have offered it as a solution if I thought it would hang.  There's no reason why it should hang, but experience has taught me that the unexpected frequently happens.  If it does hang and I can't figure out why and fix it, then you're no worse off for having tried the code.  If it works like it should, then you have a solution.  Right?

I'll get the code to together and posted within the next couple of hours.
dc197Author Commented:
Cool.  I'm sure you code will not make it hang, crappy outlook will be the culprit.
One day MS will write code that can make connections asyncronously so that the whole application - or system - doesn't hang while something waits to connect to a troublesome socket.

e.g. Using windows Explorer for FTPing to a slow server
e.g looking in Network Neighbourhood for a machine/group.domain that is no longer available
e.g. typing \\DodgyServer into windows explorer when that server happens to be unavailable
e.g. Applying rules to an IMAP folder in Outlook
e.g. resolving a domain name in Internet Explorer

etc etc

Rant over!
dc197Author Commented:
Ok great, I have followed your instructions.

For the benefit of other users, don't forget to change the name of the folder near the top of the code.


Set olkFolder = OpenMAPIFolder("\My Personal Folder Name\Inbox").Items

might be

Set olkFolder = OpenMAPIFolder("\mail.myPersonalServer.com\Inbox").Items

I'll give it a run and get back with the results.

dc197Author Commented:
That does the trick, thank you.

I tried to write some more rules to solve some of my other spam issues.  But what a bunch of crap this API is.

Firstly, sub  olkFolder_ItemAdd(ByVal Item As Object) will not take a Outlook.MailItem object as its argument, only an Object.  Making development without intellisense dificult.

Then, there is little documentation on MSDN about this object's properties.

Then, suddently VB becomes 1-based and not 0-based, so accessing the only recipient is done via foo.Recipients.Item(1) not Item(0)

Finally, guessing the properities to use is also no good:  sometimes foo.SenderEmailAddress works and sometimes it crashes (if sent from Excvhange for example).  Some story for foo.Recipients

What a bunch of shyte.

Anyway, another rant over.  My problem is solved.  Thank you.
David LeeCommented:
You're welcome.  Glad I could help out.

> will not take a Outlook.MailItem object as its argument, only an Object.  Making development without intellisense dificult.
Very true, but there is a reason and a fairly simple workaround.  The reason it only takes items of type Object is because there's no knowing up front what type of items the folder will receive and the code would generate an error if the procedure were expecting a MailItem and received anything else instead.  The way I get around the intellisense issue is to change Object to MailItem while I write the code and then change it back to Object before running it.
dc197Author Commented:
There is a problem with the rule: it never works the very first time I navigate to my folder after first opening outlook in the morning. I have to delete the spam mails by hand.  After this, on subsequent times I look in that folder, it successfully deletes the spam.  

Having to do this by hand sadly rather defeats the point of having a rule.

Do you know why this might be happening and how we can prevent it please?

Many thanks
David LeeCommented:
The rule only applies to items that arrive while the rule is running.  It was not intended to dispose of items that had arrived while Outlook wasn't running.  That's easily addressed though with a few additional lines of code.  Replace the Application_Startup sub you have with the one below.  When Outlook starts it will check all unread items in the folder you're watching.

Private Sub Application_Startup()
    Dim olkItems As Outlook.Items, _
        objItem As Object, _
        intIndex As Integer
    'Replace "My Personal Folder Name" with the name of your personal folder
    'Replace "Inbox" with the name of a folder within that personal folder if it's not called Inbox
    Set olkFolder = OpenMAPIFolder("\My Personal Folder Name\Inbox").Items
    Set olkItems = olkFolder.Restrict("[Unread] = True")
    If olkItems.Count > 0 Then
        For intIndex = olkItems.Count To 1 Step -1
            objItem = olkItems.Item(intIndex)
            If objItem.Class = olMail Then
                olkFolder_ItemAdd objItem
            End If
End Sub
dc197Author Commented:
I realise it wasn't intended to remove existing items, but that's not the problem.
The problem is that when I start outlook, and it first downloads my mail (spam included), the rule does not delete the fresh spam.  I have to delete the fresh spam myself the first time I run it, then on subsequent connections it runs fine.

Could it be something to do wiith me not pressing the "allow macros" button fast enough?

THanks for the new sunb, i'll look at that on monday

David LeeCommented:
Oops, sorry, I misunderstood.  Yes, it could be a matter of the items having arrived before you've enabled macros.  A simple test for that is to set macro security to low, which won't prompt to enable macros, and see if that does it.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.