Solved

Delete all but newest messages by thread?

Posted on 2000-04-06
42
522 Views
Last Modified: 2012-06-27
Is there a macro available anywhere that will delete all messages but the newest one in a thread? I am rapidly approaching my mailbox limit, and want to save all my mail as a reference. This way, I will have all of the information in each thread, but with 1/10th the space used. Compressing does not work. besides, this will make searching faster and is overall a good idea. If someone has it this will save a lot of people a lot of time.
0
Comment
Question by:seanick
  • 17
  • 11
  • 9
  • +2
42 Comments
 

Author Comment

by:seanick
Comment Utility
Adjusted points from 200 to 600
0
 

Author Comment

by:seanick
Comment Utility
I would really like some help with this. anyone know outlook like a god? or should I use something else? This is now a 800 MB pst file. its slowly consuming every natural resource in my computer, much like the human species in the matrix...

Points increased to 600 so someone good will look at it
0
 
LVL 12

Expert Comment

by:alandc
Comment Utility
I suggest the use of an archive database so you don't actually have to delete the older messages.  Can you give us an example though of what you are describing?  Are these emails and replys to replys (with history), etc?
0
 

Author Comment

by:seanick
Comment Utility
yeah. these messages always have the whole thread. so i dont need previous replies. i just need the latest message.

not deleting them means eating up valuable space. and im sure I dont need to explain Outlooks 2 GB bug. but just in case, once a PST file gets to 2 GB it gets totally corrupted and cannot be used anymore. IE all mail is lost. mine is now up to 1 GB +. so I need to do soemthing fast.
0
 

Expert Comment

by:skhelpdesk
Comment Utility
Are you interested in autoarchiving?
If yes, you can right-click over the inbox folder and choose the autoarchive tab. Select a time frame and the option "move old items to" and choose a location to save them in. In the future if you need to view them again you will be able to import those files back to your inbox folder. (If you still have space available)

As for making finding your messages easier in your crowded inbox, you may consider creating sub-folders under your inbox. You can store messages you need for reference but don't want them to clog up your inbox. Open your folder list, select the inbox- click on File, New, Folder -give it a name and click ok. Then move the messages into the new subfolder by dragging and dropping or right-clicking over it and choosing move to folder. Click on the subfolder whenever you need to read those messages. (It won't save space though)

My last suggestion is- print the messages and delete from inbox and deleted items folder.
0
 

Author Comment

by:seanick
Comment Utility
Adjusted points from 600 to 800
0
 

Author Comment

by:seanick
Comment Utility
whats wrong with you people? I asked for a FIX not a WORKAROUND. are you familiar with the difference between those terms?
And whats worse, did my question SOUND like I didnt know what archiving was? SPACE is an issue. Archiving is not going to change this, in fact it will likely make it worse.
I have about 45 folders, each associated with one or multiple rules, each with about 10000 mail messages. I am familiar with outlook, and I am saying there is no way in outlook to do what I want. which is to (Check the title) DELETE ALL BUT THE NEWEST MESSAGE IN A THREAD.
Man this site sucks. I tell someone I know about parallel ports and give a valid answer, they reject it because they are stupid, I ask a question and get answers like this. Thanks for nuthin.
0
 

Expert Comment

by:skhelpdesk
Comment Utility
This site is designed to be helpful. Sometimes you'll give an answer that is rejected and sometimes you receive answers you reject and sometimes you get the solution to your problem.  You take that chance. Life is short- be happy.
0
 

Author Comment

by:seanick
Comment Utility
Maybe I was a bit harsh, I don't think I explicitly explained that I didn't want more folders to sort through. The main reason I dont want to autoarchive or similar routes is because Search time is an issue as well as just avoiding the outlook PST bug.
Just the same, for things that only MIGHT be the answer, don't make it an answer, make it a comment and if it works I will accept the comment as an answer. Maybe thats why I was so upset. PLUR - SeaNICK
0
 

Expert Comment

by:skhelpdesk
Comment Utility
I can understand your frustration-anyone with software problems can relate.  Next time I'll consider making comments first. (I'm new at this and I'm trying to get used to the procedure). Good Luck and I hope you get your problem solved.
0
 
LVL 12

Expert Comment

by:alandc
Comment Utility
What we need is more detailed information if we are to help. Here are some straightforward questions. Answer them and mention any related information however remotely connected that might help.
1) What is the format are the messages received?  Are they entirely textual, encoded, or threaded (with other messages not just quoted but actually imbedded inside them)?
2) How valuable are they?  Should say... a few get accidentally deleted because they contained data similar to a previous post or would it be better if only 80% got weeded in the effort to maintain all threads?
3) Are there any fields that can be counted on to remain either static or variable like the subject field is always the same or always prefixed by a "re:" or "attn:"?
4) Is the mail generated by a auto responder, compellation generator, or by human responses, forwards, etc.?

Or to just sum it all up in one question. Is the input data formatted and standardized enough that a query could actually process it or will it require intelligence (human intervention) to determine its relevance and value?  If you want us to determine the answer to that question then of course more information is needed.
0
 

Author Comment

by:seanick
Comment Utility
1. all formats. plaintext, encrypted, HTML, MIME and RTF. All have the entire previous thread (Outlook default). This is why I only need the latest one.
2. Some threads get multiple replies to a single message, so if only one is saved, all other replies are lost. This is not a tragedy, in most cases the most recent is all I need. and if I lose a less recent one with better info, I wont care because the alternative is to not know about it at all.
3. Ignore all FWD: and RE:. (and spaces between them or the titles) all other words should remain as the thread title. See below for more info.
4. Mail is generated by multiple people who think they know what they are talking about, and if someone has a correction or more info they reply. Very few are automatic, I auto delete mail from major automatic mail producers. Dont worry about this, it is not a factor.

Outlook has code that knows how to sort all messages by conversation. I have found this works in 99%+ of threads (IE I have never seen a thread other than threads with changing titles that does not get put in the same conversation). I would not mind sorting by conversation and running the macro on just that folder. that would be worth it (Im talking 15000 messages in a couple folders that could be trimmed to 2500 or so, and still retain 90% of pertinent info).

Please ask if you have any more questions
Thanks
NICKH
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
You're searching for a macro that takes a date as an input and goes from folder to folder and deletes all messages before that date?
0
 

Author Comment

by:seanick
Comment Utility
Not quite.
Take Subject line, search for most recent date for all messages with that subject, and delete all messages with that subject and a different date
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
What version of Outlook?

I could write something to do this for you, but I would need time.

I need to know what the version is since I haven't gotten around to buying VB for myself yet and will need to write this using Outlook.  If you have 97/98 I will need to put the code into a form.  2000 allows the code to attached to a toolbar button.

The best way to buy the time I need is to use the autoarchive to permanently delete items (as suggested previously).  My default is 3 months.  It may not be the ideal solution but it will help.

0
 

Author Comment

by:seanick
Comment Utility
Outlook 2000 SR1.
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
I wrote some stuff already I just want to be sure what exactly it needs to do. Delete all messages with a specific subject line that were received before a specific date?
If so, it's not a problem.
0
 

Author Comment

by:seanick
Comment Utility
nope sorry. no specific date. just where there are newer messages with the same subject
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
How do you define "new"?
0
 

Author Comment

by:seanick
Comment Utility
date being larger in seconds than a previous date.
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
so you want to keep only 1 message which is the newest?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
I wrote the code. It keeps only the newest messages in a thread in a folder you choose. It has a problem that it doesn't recoginize several REs or FWs like "re:re:subject".
0
 

Author Comment

by:seanick
Comment Utility
Cool. email it to me at nickh@microsoft.com, if the code works the points are yours
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
If Yiftach_D's code isn't what you want, I have finished a routine which will do what you want.

The routine will handle multiple Re/FW/FWD on the subject.

It also provides a status update as it is processing (something you probably want with as many items as you have in your folders).

When it is complete it puts a message in the Drafts folder with a subject line that tells you how many items were deleted and how many items are left in the folder.

The code can be attached to a toolbar button, if you don't know how let me know.

The code is only about 60 lines.

=======================

Yiftach_D - Could you please post your code?

Here is my code
==================

Sub ThreadDeleter()
    Dim statusItem As MailItem
    Dim fld As MAPIFolder
    Dim totDeleted As Long
    Dim itemsChecked As Long
    Dim txtSubject As String
    Dim RecentDate As Date

    totDeleted = 0
    itemsChecked = 0
    Set fld = Application.ActiveExplorer.CurrentFolder
    For Each MailItem In fld.Items
        txtSubject = RemovePrefix(MailItem.Subject)
        RecentDate = MailItem.ReceivedTime
        totDeleted = totDeleted + DeleteDups(txtSubject, RecentDate)
        itemsChecked = itemsChecked + 1
        If itemsChecked = 50 Then
            itemsChecked = 0
            MsgBox "You have deleted " & totDeleted & " items so far."
        End If
    Next
    Set statusItem = Application.CreateItem(olMailItem)
    statusItem.Subject = "<< Deleted " & totDeleted & " items in folder " & fld.Name & "There are " & fld.Items.Count & " remaining items. >>"
    statusItem.Close olSave
    Set statusItem = Nothing
    Set fld = Nothing
End Sub

Function DeleteDups(txtSubject As String, RecentDate As Date) As Long
    Dim txtCurrent
    Dim intDeleted
    intDeleted = 0
    Set fld = Application.ActiveExplorer.CurrentFolder
    For Each MailItem In fld.Items
        txtCurrent = RemovePrefix(MailItem.Subject)
        If txtCurrent = txtSubject Then
            If RecentDate > MailItem.ReceivedTime Then
                MailItem.Delete
                intDeleted = intDeleted + 1
            Else
                RecentDate = MailItem.ReceivedTime
            End If
        End If
    Next
    DeleteDups = intDeleted
    Set fld = Nothing
End Function

Function RemovePrefix(txtSubject As String) As String
    RemovePrefix = UCase(Trim(txtSubject))
    Do While Left(RemovePrefix, 3) = "RE:" Or Left(RemovePrefix, 3) = "FW:" Or Left(RemovePrefix, 4) = "FWD:"
        If Left(RemovePrefix, 3) = "RE:" Or Left(RemovePrefix, 3) = "FW:" Then
            RemovePrefix = Trim(Mid(RemovePrefix, 4))
        Else
            RemovePrefix = Trim(Mid(RemovePrefix, 5))
        End If
    Loop
End Function

0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
Hi,
Nice code, so I see you loop while there's a "re:" or "fw:", that's nice. If would have done that my code would have worked better, but I don't want to copy, so take the points. My code uses a MailItem array, that uses ReDim, that represents a thread. Then it loops through it and keeps only the latest item. Do you want to see the code?
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
Three monthes to finish the code, ha?
0
 

Author Comment

by:seanick
Comment Utility
:) ya that was a short three months.
OK I will try to get these working today, I actually don't have any idea how to add this to Outlook.
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
seanick,

It was nice working for nothing... but at least I made him write his code faster :-). To add this code create a COM addin or I'll send you the template. And you can also ask mohnshine to compile it and send it to you. I was so close...

Hope it works,

Yiftach.

0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
I didn't mean it would take three months to write.

What I meant was that I have autoarchive set to automatically delete items that are at least 3 months old in my folders.  I find that if an item is  that old I probably won't look at the item anyway.

but anyway ... yes I would like to see your code Yiftach_D

================
To add the code in OL is easy.

On the Menu select Tools > Macro > Visual Basic Editor ( or ALT-F11 )

Another window will open.

Select ThisOutlookSession in the upper left pane (may have to click the +) if it is not already selected.

Copy the code into the right hand pane.

Save the code. (File > Save VBAProject.OTM or CTRL=S )

Close the VB Editor Window.

=======================

Now you can link the code to a toolbar button.

Now select View > Toolbars > Customize (or right-click the toolbar and Customize) << Note the VB Editor must be closed as well as any other Outlook Dialog boxes >>

In the displayed dialog box select the Commands Tab.  Select Macros in the left pane.  The right pane should show all the macros yooou can link to a button.  For this one you are looking for Project1.ThisOutlookSession.Threa (of course you can't resize or scroll the pane to see the whole name).  Select it and drag it to the toolbar.

After it is on the toolbar, select it.  The modify selection button will activate and you can change it to the default style and assign it to the trashcan icon.

================

One final note - even though you saved the code in VB Editor, when you close OL it will prompt you if you want to save the VBAProject.OTM file again.  Select yes to save the code.

0
 

Author Comment

by:seanick
Comment Utility
I guess I probably should have told you that I already figured it out.

I have a couple problems with it, not really problems but things I would change given the chance.
1. CPU usage is really high
2. Outlook will not respond to anything else while the code is running
3. the code takes hours for a small folder (300 messages). I havent yet been able to complete a larger folder, as I actually need my email.
4. the occasional popup is more annoying than useful ( I removed this myself, thats easy)

if you can fix those I will give you the points immediately.
if not, well I will maybe work on it a little and see what I can come up with, and then give the points to whoever got closest
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
I tried it with a folder with over 600 items in it and it went pretty fast (less than 2 minutes).

Also all the items which get deleted go to the Deleted Items folder.  I suggest emptying it before you run the code.

Another factor might be the size of your mailbox.

The items in a folder collection are not stored in any particular order, so it is possible that a combination of mine and YiFtach_D's code might be a better solution.

0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
i don't know how many folders you have, but a way to speed this up would be to export your larger folders to another pst.  Compact your pst and try again.

Remember the reason you are doing this is because you are reaching the size limits.  Anything you can do to decrease the size would be helpful.
0
 

Author Comment

by:seanick
Comment Utility
Dont think I am not grateful because I am, I just need to work out a couple issues. if you think its because of folder size, then I will do it this way: Create 2 new PST's, move a folder to PST1, run the macro, then move it to PST2. loop. till all folders are gone from PST0. then delete PST 0 and 1 and use PST2 as main. This is because Compacting does not seem to do anything, I have deleted large folders and compacted, the compacting process takes hours but decreases maybe 1K in size.

Thanks for the idea
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
That sounds like a good idea.  Don't forget to dump the trash in the Deleted Items folder.

===============

I can't stress test this well enough here because I have never had 15,000 items in a mailbox, let alone a single folder.

When I am done with an e-mail I have a tendency to shift-delete it (usually within microseconds of reading it).
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
I was looking at the code and you should delete these to lines in the DeleteDups Function:

Set fld = Application.ActiveExplorer.CurrentFolder

Set fld = Nothing

-------
These lines are a holdover from something else that I was trying to do and are not needed.

It should help things a bit since it will not be creating and deleting an object that isn't used every time DeleteDups is called (at least once per thread).  Don't expect a ignificant change, since you still have a monster mailbox.

I am also working on a more stripped down version (removing some of the bells and whistles)
0
 
LVL 3

Expert Comment

by:mohnshine
Comment Utility
OK - Stripping out all of the messages did not improve the speed.

Believe it or not it was significantly faster with msgboxes!!! Approx 50 seconds with msgboxes, and 90 seconds without.  I guess OL needs a break once in a while, even if it is just long enough to hit enter or click the mouse button.

I hope the one folder at a time method helps.
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
Now the moment we've all been waiting for... MY CODE!

this code is module
Public golApp As Application
Public gnspNameSpace As NameSpace

'this code I put in the designer since I use com addins, you can put in the VB Editor just remember to put the declarations there too!!!

Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant)
On Error Resume Next

Set golApp = CreateObject("Outlook.Application")    ' Application object.
Set gnspNameSpace = golApp.GetNamespace("MAPI") ' Namespace object.

Set inbox = gnspNameSpace.GetDefaultFolder(6)
Set test = inbox.Folders("test")
Set myitems = test.Items

Dim latest As Date
Dim thread() As MailItem

For Each itm In myitems
    i = 0
    subj = itm.Subject
    resubj = "re:" & itm.Subject
    fwsubj = "fw:" & itm.Subject
    For Each t In myitems
'this is the place where it checks if
'it belongs to the thread, the part
'with that if I would've put your
'function it would've worked!
        If (t.Subject = subj) Or (t.Subject = resubj) Or (t.Subject = fwsubj) Then 'change to instr
        ReDim Preserve thread(i + 1)
        Err.Clear
        Set thread(i) = t
        If Err.Number <> 0 Then Exit For
        i = i + 1
        End If
    Next t
    For j = 0 To UBound(thread) - 1
        If thread(j).ReceivedTime > latest Then
            latest = thread(j).ReceivedTime
        End If
    Next
    For h = 0 To UBound(thread) - 1
        If thread(h).ReceivedTime < latest Then
        thread(h).delete
        End If
    Next
    latest = CDate(1 / 1 / 1900)
    ReDim thread(0)
Next itm
End Sub

I don't think it's faster, but you can give it a shot.
0
 

Author Comment

by:seanick
Comment Utility
hmm I am encountering problems with your code MohnShine. Performance  isnt that bad, the only problems are still that Outlook hangs dead when it is running. but once in a while I get a popup "This form could not be opened. " I have no idea which messages this is on but probably the messages which are encrypted, or OOFs, or recalls, ...
Anyway right now I just click OK and continue. This is a really cool macro though, so if you were to ever give it to anyone else, it would be nice if that problem was not there.
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
In my code if you want to check. Instead of:
Set inbox = gnspNameSpace.GetDefaultFolder(6)
Set test = inbox.Folders("test")
Set myitems = test.Items

write
Set myitems = activeexplorer.currentfolder.items
0
 
LVL 3

Accepted Solution

by:
mohnshine earned 800 total points
Comment Utility
I have finished a much better version.  It processed a folder WITH 2500 ITEMS in LESS THAN 30 SECONDS.

The deleted items are completely removed from the mailbox.

Simply replace my previous code with this code.

==============
Sub ThreadDeleter()
    On Error GoTo errorhandler
   
    Dim fld As MAPIFolder
    Dim fldItems As Items
    Dim statusItem As MailItem
    Dim txtSubject As String
    Dim RecentDate As Date
    Dim itemsChecked As Integer
    Dim itemCnt As Integer
    Dim innerItemCnt As Integer
    Dim looper As Boolean
       
    Set fld = Application.ActiveExplorer.CurrentFolder
   
    Set fldItems = fld.Items
    fldItems.ResetColumns
    fldItems.SetColumns "[ReceivedTime],[Subject]"
    fldItems.Sort "[ReceivedTime]", True
   
    itemsChecked = 1
    If fldItems.Count > 0 Then
        looper = True
        itemCnt = 1
        Do While looper = True
            txtSubject = RemovePrefix(fldItems.Item(itemCnt).Subject)
            RecentDate = fldItems.Item(itemCnt).ReceivedTime
           
            For innerItemCnt = fldItems.Count To itemCnt + 1 Step -1
                If RemovePrefix(fldItems.Item(innerItemCnt).Subject) = txtSubject Then
                    fldItems.Remove (innerItemCnt)
                End If
            Next
       
            Set fldItems = fld.Items
            fldItems.ResetColumns
            fldItems.SetColumns "[ReceivedTime],[Subject]"
            fldItems.Sort "[ReceivedTime]", True
       
            itemsChecked = itemsChecked + 1
            If itemCnt > fldItems.Count Then
                looper = False
            Else
                If itemsChecked > 25 Then
                    itemsChecked = 1
                    MsgBox itemCnt & " items checked."
                End If
            End If
            itemCnt = itemCnt + 1
        Loop
    End If
   
    Set fldItems = Nothing
    Set fld = Nothing

    GoTo noerrors
   
errorhandler:
    MsgBox errline & vbCrLf & fldItems.Count & vbCrLf & itemCnt & vbCrLf & innerItemCnt
    Set statusItem = Application.CreateItem(olMailItem)
    statusItem.Subject = "An error has occured"
    statusItem.Body = Err.Description & vbCrLf
    statusItem.Body = statusItem.Body & "flditems count = " & fldItems.Count & vbCrLf
    statusItem.Body = statusItem.Body & "Itemcnt = " & itemCnt & vbCrLf
    statusItem.Body = statusItem.Body & "inneritemcnt = " & innerItemCnt
    statusItem.Close olSave
    Set statusItem = Nothing

noerrors:
End Sub

Function RemovePrefix(txtSubject As String) As String
    RemovePrefix = UCase(Trim(txtSubject))
    Do While Left(RemovePrefix, 3) = "RE:" Or Left(RemovePrefix, 3) = "FW:" Or Left(RemovePrefix, 4) = "FWD:"
        If Left(RemovePrefix, 3) = "RE:" Or Left(RemovePrefix, 3) = "FW:" Then
            RemovePrefix = Trim(Mid(RemovePrefix, 4))
        Else
            RemovePrefix = Trim(Mid(RemovePrefix, 5))
        End If
    Loop
End Function
0
 

Author Comment

by:seanick
Comment Utility
Comment accepted as answer
0
 
LVL 1

Expert Comment

by:Yiftach_D
Comment Utility
That's good using SetColumns, it takes less time to execute.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Learn more about how the humble email signature can be used as more than just an electronic business card. When used correctly, a signature can easily be tailored for different purposes by different departments within an organization.
Use these top 10 tips to master the art of email signature design. Create an email signature design that will easily wow recipients, promote your brand and highlight your professionalism.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This Experts Exchange video Micro Tutorial shows how to tell Microsoft Office that a word is NOT spelled correctly. Microsoft Office has a built-in, main dictionary that is shared by Office apps, including Excel, Outlook, PowerPoint, and Word. When …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now