The Wayback Machine - https://web.archive.org/web/20150209120916/http://www.slipstick.com:80/developer/macro-move-aged-mail/

Use a Macro to Move Aged Email in Outlook

Last reviewed on February 8, 2015   —  87 comments

We had a question from a user who wanted a macro to move mail to a subfolder as it aged. While you could use AutoArchive to do this quickly and easily, no coding required, AutoArchive moves mail to a *.pst file, not a subfolder. If you don't care where the mail is moved to, just that its out of your Inbox, use AutoArchive, set to run every 1 day and configure the Inbox archive setting to the desired number of days.

To use, assign the macro to a command button and run as needed. You could also use this as an application start macro and have it run when Outlook starts.

If you aren't a big fan of moving mail, you can leave it in the Inbox and use custom views to hide older mail.

There are 4 macros on this page plus one code snippet. Two macros show you how to move messages to a folder within your current data file and to move messages to a folder in a new data file. The third macro on this page shows you how to use a Select Case statement to move different Outlook items types, using a different age for each item type. The code sample gives you the code needed to move only messages you've replied to or forwarded.

 

VBA Macro to Move Aged Email Messages

This code sample checks the default Inbox for email older that 7 days and moves any it finds to a subfolder of the Inbox, called Old.

You'll need to set the age, in days, to your desired number. This sample uses 7 days. You'll also need to replace the data file name.

In this sample, the data file name is an email address because that is what Outlook 2010 uses for data file names. You'll need to change this as well as the folder path you are moving the email to.

Tested in Outlook 2010 and Outlook 2013 with an Exchange mailbox.

The Date field can either be SentOnor ReceivedTime when you are working with email or meeting request and responses.

Sub MoveAgedMail()

    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim lngMovedItems As Long
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String
    
    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    
    ' use a subfolder under Inbox
    Set objDestFolder = objSourceFolder.Folders("Old")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
        Set objVariant = objSourceFolder.Items.Item(intCount)
        DoEvents
        If objVariant.Class = olMail Then
            
             intDateDiff = DateDiff("d", objVariant.SentOn, Now)
             
            ' I'm using 7 days, adjust as needed. 
            If intDateDiff > 7 Then

              objVariant.Move objDestFolder
              
              'count the # of items moved
               lngMovedItems = lngMovedItems + 1

            End If
        End If
    Next
    
    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s)."
Set objDestFolder = Nothing
End Sub

 

Move messages to a different data file

If you want to move the messages to a new data file, you need to change the destination folder path: Set objDestFolder = objNamespace.Folders("me@domain.com").Folders("Inbox").Folders("Old") to use the GetFolderPath function: Set objDestFolder = GetFolderPath("new-pst-file\folder-name").

That line is the only change needed to use a different data file (well, that line and the function).

Tip: A function can be used by any macro, so I keep the functions together in a separate module. When I add a macro that uses a function, I can easily see if I have that function already.


Sub MoveAgedMail2()
 
'Get the function from http://slipstick.me/qf
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim lngMovedItems As Long
    Dim intCount As Integer
    Dim intDateDiff As Integer

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
     
 'Use a folder in a different data file   
           Set objDestFolder = GetFolderPath("my-data-file-name\Inbox")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
        Set objVariant = objSourceFolder.Items.Item(intCount)
        DoEvents
        If objVariant.Class = olMail Then
             
             intDateDiff = DateDiff("d", objVariant.SentOn, Now)
              
           ' adjust number of days as needed.
            If intDateDiff > 60 Then

              objVariant.Move objDestFolder
               
              'count the # of items moved
               lngMovedItems = lngMovedItems + 1

            End If
        End If
    Next
     
    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s)."
Set objDestFolder = Nothing
End Sub

 

Move mail you've replied to or forwarded

With a few simple changes, you can convert the macro above to move messages that were replied to or forwarded.

Begin by adding these lines to the top of the macro with the other Dim statements.

Dim lastverb, lastaction As String
Dim propertyAccessor As Outlook.propertyAccessor

Using the first macro on this page as the base, replace the code block between the If objVariant.Class... and objVariant.Move lines with the code block below. Because Reply, Reply all, and Forward values are 102, 103, and 104, and to the best of my knowledge, those are the only possible values, we can leave the lastaction value at 7 (was intDateDiff in the original macro).

        If objVariant.Class = olMail Then
       
     Set propertyAccessor = objVariant.propertyAccessor

       lastverb = "http://schemas.microsoft.com/mapi/proptag/0x10810003"
       lastaction = propertyAccessor.GetProperty(lastverb)
             
    ' 102, 103, 104 are replied, forwarded, reply all
           If lastaction > 7 Then
             
           ' use your datafile name and each folder in the path
           ' the example uses an email address because Outlook 2010
           ' uses email addresses for datafile names
           Set objDestFolder = objNamespace.Folders("diane@domain.com"). _
                   Folders("Inbox").Folders("completed")
 
              objVariant.Move objDestFolder

 

Use Case Statements instead of IF statements

This code sample uses Case statement to get the ReceivedTime or CreationTime of email, meeting requests and responses, as well as read receipt reports, then plugs the date value into the calculation. It also allows you to use different dates for each group of items types.

Sub MoveAgedItems()
 
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim obj As Variant
    Dim sDate As Date
    Dim sAge As Integer
    Dim lngMovedItems As Long
    Dim intDateDiff As Integer
    Dim intCount As Integer

    
    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    Set objDestFolder = objNamespace.Folders("diane@domain.com"). _
                   Folders("Inbox").Folders("Old")
 
    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set obj = objSourceFolder.Items.Item(intCount)
        DoEvents
 
     Select Case obj.Class
        Case olMail
            sDate = obj.ReceivedTime
            sAge = 180
                    
        Case olMeetingResponseNegative, _
            olMeetingResponsePositive, _
            olMeetingCancellation, olMeetingRequest, _
            olMeetingAccepted, olMeetingTentative
            sDate = obj.ReceivedTime
            sAge = 10
                    
        Case olReport
            sDate = obj.CreationTime
            sAge = 10
        Case Else
            GoTo NextItem
      End Select
        
intDateDiff = DateDiff("d", sDate, Now)
   If intDateDiff > sAge Then
      obj.Move objDestFolder
      
        lngMovedItems = lngMovedItems + 1
  End If
  
NextItem:
Next

    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s)."
Set objDestFolder = Nothing

End Sub

How to use macros

First: You will need macro security set to low during testing.

To check your macro security in Outlook 2010 or 2013, go to File, Options, Trust Center and open Trust Center Settings, and change the Macro Settings. In Outlook 2007 and older, it’s at Tools, Macro Security.

After you test the macro and see that it works, you can either leave macro security set to low or sign the macro.

Open the VBA Editor by pressing Alt+F11 on your keyboard.

To put the code in a module:

  1. Right click on Project1 and choose Insert > Module
  2. Copy and paste the macro into the new module.

More information as well as screenshots are at How to use the VBA Editor

About Diane Poremsky

Diane Poremsky
A Microsoft Outlook Most Valuable Professional (MVP) since 1999, Diane is the author of several books, including Outlook 2013 Absolute Beginners Book. She also created video training CDs and online training classes for Microsoft Outlook. You can find her helping people online in Outlook Forums as well as in the Microsoft Answers and TechNet forums.

Please post long or more complicated questions at Outlook forums by Slipstick.com.

87 responses to “Macro to Move Aged Email Messages”

  1. Chuck Etheridge

    nThanks for your thoughtful reply, however though i use this machine quite a bit - being retired what else is there to do - i'm a bit intimidated by the idea of doing as you suggest. On top of that, I''d have to go through the whole bqtch of mails to find just which mails to get rid of and as most of isn't ov vitl importance I think htat an entire deleiton could well be in order.

    1. Diane Poremsky

      What version of Outlook do you use? Instant Search should make it easy to find anything you need - whether it is in your inbox or another folder. Or, if you just want to hide older mail, use a search folder to display messages that arrived today, or that are unread. You can also use Views to hide older messages if you like to see a "clean" inbox but don't want to move or delete messages. If you are using Outlook 2003 and above with the new pst format, size doesn't matter much - but I would get in the habit of deleting mail you really don't need as you receive or read it, like advertising.

  2. Woodgrain

    Thanks very much for this, I thought this would be a common request, yet there are so few resources for this online.

    How would I modify this so I can run it in Outlook 2007 on my exchange connected email?

    Thank you!

    1. Diane Poremsky

      It should work fine with Outlook 2007. It works with the default email account, so it should work fine with your exchange account too.

  3. AJ

    Hi Diane,

    Can you let me know if you have a script that we can run on outlook 2010 , which can forwards a mails to a specific ID for those mails that are aged more than 30 minutes in inbox

    This macro to run automatically in every 35 minutes. Note this is an exchange account.

    1. Pennie

      Can anyone tell me why this isn't working? This macro is moving all of my Read mail when I only want it to move the messages from a specific sender.

      Sub HelpDesk3()

      On Error Resume Next

      Set objOutlook = CreateObject("Outlook.Application")
      Set objNameSpace = objOutlook.GetNamespace("MAPI")
      Set objFolderSrc = objNameSpace.GetDefaultFolder(olFolderInbox)
      Set objFolderDst = objFolderSrc.Folders("MoveTo")

      Set colItems = objFolderSrc.Items
      Set colfiltereditems = colItems.Restrict("[UnRead] = False")

      For intMessage = colfiltereditems.Count To 1 Step -1
      If objVariant.Sender = "me@me.com" Then
      colfiltereditems(intMessage).Move objFolderDst
      End If
      Next

      End Sub

    2. Diane Poremsky

      try using senderemailaddress here instead of sender:
      If objVariant.Sender = "me@me.com" Then

  4. Gilad

    Is there a way (without macros) to copy or move all the emails in my deleted folder to another folder on a daily basis, automatically? Like a scheduled task.
    Our admin has a process running every day that deletes all the emails in "deleted" folder. but I am using that folder as a temporary folder and/or archive (after I read and act).
    I am happy that each time I hit "delete" the email will move/copy to different folder (other than "deleted").

    1. Diane Poremsky

      you would need to use a macro. If the admin is not deleting mail daily you could use autoarchive to copy it to a pst when its a day old. Otherwise, if using Outlook 2010, set up a quick step to move mail instead of hitting the delete button.

  5. Gilad

    Thanks, I am using Outlook 2010 (and Exchange).
    I did set up a "quick step" but that requires me to go to the folder select the emails ( I select all of them), and then click the "quick step".
    Is there a way to have the "quick step" run automatically? like once a day? and in the background? So I don't have to remember this, go to the folder, etc...

    1. Diane Poremsky

      No, QS can't run automatically. You'll need to use a macro, which can be configured to run when something happens, like a reminder on a task that is in a specific category.

  6. Gilad

    Thanks.
    Is there a generic macro that I can use?

    1. Diane Poremsky

      Use the code at task reminder macro. Remove everything except the 2 if... end if blocks and replace it with the name of the macro you want to run.
      MoveAgedMail

      I'd remove the If intDateDiff > 7 Then (and its matching end if) so it works on all mail in the folder.
      also need to use Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderDeletedItems)

      alternately, you could use an item add macro that watches the deleted items folder and moves everything to a new folder as its deleted.

      Or... simplify your life and create and use a quick step to move stuff you want to keep and only use the deleted items folder for stuff you don't want. Once you get in the habit, Ctrl+Shift+1 can be second nature. if your mouse or keyboard supports programmable keys you might be able to reprogram a key for the shortcut.

  7. Gilad

    Thanks, I like this idea: use an item add macro that watches the deleted items folder and moves everything to a new folder as its deleted.
    Is there an easy Macro you can recommend?

    1. Diane Poremsky

      I'm sure I have one around here that just needs a little tweaking, like this one. :)
      Private WithEvents Items As Outlook.Items

      Private Sub Application_Startup()
      Dim NS As Outlook.NameSpace
      Set NS = Application.GetNamespace("MAPI")
      Set Items = NS.GetDefaultFolder(olFolderDeletedItems).Items
      Set NS = Nothing
      End Sub

      Private Sub Items_ItemAdd(ByVal Item As Object)

      Set fldMove = Session.GetDefaultFolder(olFolderInbox).Folders("Deleted Stuff")
      Item.Move fldMove

      End Sub

      This macro assumes the folder is you are moving to is under the inbox.

    2. Diane Poremsky

      Actually, you'll probably want to use this instead of the other itemadd version so it only looks at mail -
      Private Sub Items_ItemAdd(ByVal Item As Object)
      If TypeOf Item Is Outlook.MailItem Then
      Set fldMove = Session.GetDefaultFolder(olFolderInbox). _
      Folders("Deleted Stuff")
      Item.Move fldMove
      End If
      End Sub

      And the only way to really delete mail is using Shift + Delete to permanently delete items.

  8. Gilad

    Thanks.
    I will try this...

  9. James

    I'm just now starting to try to learn to write and use macros. How difficult would it be for me to add another criteria to this macro in that it would move certain emails with certain subject lines to a designated subfolder after xx days?

    1. Diane Poremsky

      It won't be hard at all. stick objVariant.subject="whatever" and in the if line. You could use a separate if... then statement inside the date statement instead.

  10. James

    Thank you for the quick reply. I'm starting to beat my head against the wall, lol. I've been reading and researching this for the last week and when I started I thought that may work and tried it early on but I get a runtime error of '424': object required when I try that. I've been trying to figure it out but I just can't seem to get it to work. FYI, the original macro works great at moving emails to specified folders by date alone, so it's not that.... Any ideas?

    1. Diane Poremsky

      That's my fault - i was on my netbook and didn't review the macro - most use item, so i assumed it did too. It uses objVariant instead.

      If intDateDiff > 7 AND objVariant.Subject = "whatever" Then

      or you can use this format
      If intDateDiff > 7 Then

      If objVariant.Subject = "whatever" then
      'do whatever
      end if

      end if

  11. James

    Worked like a charm! Thank you for the assistance! This has been a good learning experience.

  12. Örjan Kihlbaum

    Hello!

    I am interested in an macro that (perhaps using quick step) that sets an reminder on an email, moves it to a specific folder. Then when the reminder is triggered it moves it back to the inbox, marks it unread and flags it.

    Is that possible?

    I am on Outlook 2013 btw. :)

    Regards,

    1. Diane Poremsky

      The quick step can set a flag and move the message (its limited to the predefined flags) or you can use a macro to set a reminder, like 3 days from now, and move the message. Add it to the ribbon and its as easy as a quick step.

      A second macro is triggered by the reminder - basic idea is here at run macro when reminder fires. You need to identify the item and move it back to the inbox. Of those two steps, identifying the reminders associated message might be the harder task. Item.Move Session.GetDefaultFolder(olFolderInbox) should handle it.

    2. Diane Poremsky

      Actually my brain is on vacation. :) The message is identified as the item by the reminder - try this version. I would probably set a category using the quick step, especially if you don't want all mail moved back.

      Private Sub Application_Reminder(ByVal Item As Object)

      If Item.MessageClass <> "IPM.Note" Then
      Exit Sub
      End If

      If Item.Categories = "Needs Followup" Then
      Exit Sub
      End If
      Item.Move Session.GetDefaultFolder(olFolderInbox)

      End Sub

  13. Eduardo Carvalho

    Good morning!

    Would you like to help me, please, to use this script to move emails to a default folder to another.

    Ex.:
    My email is default setting to a file "Outlook.ost" and I have to move the items to a subfolder that is configured in a file "*. Pst".

    My Outlook is in Portuguese, the names of the folders in the script must be in Portuguese or in English?
    Ex.: “Caixa de Entrada = Inbox.

    This is easy?
    I will be very grateful if you can help me.

    1. Diane Poremsky

      You would use this to call the folder in another data file:
      Set objDestFolder = GetFolderPath("New PST\Test Cal")

      and use the GetFolderPath function.

      I'll add an updated macro to the page with the necessary code changes.

  14. Eduardo Carvalho

    You could send me a copy of cógido to email or post comments in response.
    I would like a model of the script so I just alter the paths and file names.

    Sorry for the inconvenience.
    Thank you!!

    1. Diane Poremsky

      The new code sample is at #newpst - you'll need to change the pst path in the macro and get the function.

  15. Rob

    Hi Diane,

    I'm trying to use the second script and I keep running into run-time error 438 (Object doesn't support this property or method) while using Outlook 2010. The error points to the following:

    intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    I looked over the DateDiff function and other areas and can't determine what's wrong. Any thoughts?

    Thank you...

    1. Diane Poremsky

      I don't think the problem is with that line. Unless... you are running it against a different folder type. It checks for oMail, so meeting requests should cause a problem. Try adding on error resume next before the For intcount... line. Does it run and if so, how any messages are moved? The ones it skips may give you a clue.

  16. Adam

    If I wanted to specify to move items older than 7 days and sent from a specific e-mail address how would I do that?

    1. Diane Poremsky

      If intDateDiff > 7 AND If objVariant.sender = "alias@domain.com" Then

      Should work. If Outlook 2013, objVariant.senderemailaddress should work too.

  17. Diane Poremsky

    This works here, in Outlook 2010:
    If intDateDiff > 7 And objVariant.SenderEmailAddress = "alias@domain.com" Then

  18. Merdan Bayramov

    Dear Diane,

    Pls advise as I have tried the combination of "If intDateDiff > 7 And objVariant.SenderEmailAddress = "alias@domain.com" Then" and included a sender's email address, but it msgbox prompts that "Moved 0 messages". But, if I leave only this part of the code "If intDateDiff > 7 Then", then the code work just fine. I use MS Office 2010, corporate email and Microsoft exchange. Any ideas as what may be done?

    Regards,

    Dan

  19. Eduardo Carvalho

    Good morning!

    Diane, I'm sorry again for the inconvenience.
    I appreciate your help and I hope it doesn’t bother her anymore.

    I follow their guidelines to create an example of Macro. Making only minor adjustments.
    Unfortunately presented a small error while performing the Macro.
    A small window with the following information (below) shows:
    "Compile error: 'Sub' or 'Function' not defined".
    Below is the part of the macro fails (The text "GetFolderPath" appears selected in yellow):

    "
    'Create a folder in a different file date
    Set objDestFolder = GetFolderPath("Eliane - Emails\Caixa de Entrada")
    "

    I searched the internet but have not found solutions.
    Please, if possible, help me fix this problem.
    How I would I directed to another folder PST files?
    The target for the new PST file, must have only the name of the folder or the actual file path?

    Thank you!

    1. Diane Poremsky

      Did you add the GetFolderPath macro to the module? http://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/

  20. Karen

    Hi Diane :)
    My Outlook2010 has a number of email accounts and I want to use this to work with a specific Inbox, and not my default. Here are some of the details that I have:

    1) 5+ accounts
    e: me@you.com - datafile name: 1 meatyou
    e: you@mine.com - datafile name: 2 youandmine
    e: test@si.com - datafile name: 3 testingsilly
    etc

    2) My datafiles, pst are not saved in the normal folders, I moved them as per your "move .pst guide". Will that cause an error?

    3) I have run this code (http://www.vboffice.net/sample.html?lang=en&mnu=2&smp=65&cmd=showitem) to get the folder details of where I need the emails to go and it shows: \\3 testingsilly\Inbox\ialerts

    4) I have installed your "getfolderpath" in to a common module (not on startup) and have set:
    Set objDestFolder = GetFolderPath("\\3 testingsilly\Inbox\ialerts")

    Basically I've tried both option 1 & 2 and I still result in a '0' result. Yet there are mail items in my inbox over 1 month old.

    I'm stuck, I have a lot of non-default variables :) I'd like to adapt this to also move reports I get daily, that aren't in my Inbox.

    e: me@you.com - datafile name: 1 meatyou
    \\1 meatyou\Inbox\reports\daily

    to:
    e: test@si.com - datafile name: 3 testingsilly
    \\3 testingsilly\Inbox\Reports\FY13-14

    Please advise :)

    Thank you in advance

    1. Diane Poremsky

      2. No, the hard drive location is not a factor.

      3. You can right click on the folder, choose properties and get the path - but any way you do it, you don't need the leading \\ in the path.

  21. Karen

    Thanks Diane,
    I still stalled out, however I did make the following change:
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox) to:

    Set objSourceFolder = objNamespace.Folders("9 ISS iAlerts").Folders("Inbox") and it works.

    Now I need to work out some IF statements so they don't all disappear to the one folder. :) I have found that using the 2nd code with the GetFolder Function it works to move either between existing Inbox/folders and /new account/inbox/folders

    So I don't need to run the 2 versions of the code in different modules.

  22. Karen

    Hi again, I've run this now a few times however it leaves behind read receipts.
    Is this because they are different objects?
    How can I include them in the move?
    Thank You :)

    1. Diane Poremsky

      Yes, it is because they aren't mailitems, they are reportitems. You have two choices: remove the If statement (and matching End if) and move everything or check for olReport too.
      If objVariant.Class = olMail or objVariant.Class = olReport Then

  23. Karen

    Thank you :)
    I now have a new error:
    "Run-time error '438':
    Object doesn't support this property or method"

    error line: intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    Full code:
    Dim objVariant As Variant

    If objVariant.Class = olMail Or objVariant.Class = olReport Then

    'Perform logic to determine difference between NOW and the date of the item.
    intDateDiff = DateDiff("d", objVariant.SentOn, Now)
    'If Date is older than 0 days (or today) then apply the following logic, change as needed
    If intDateDiff > 21 Then

    All the mail moves correctly, it is just the "Return Receipt (Displayed)" that don't move.

    1. Diane Poremsky

      The Return receipts don't have report the dates the same way - you'll need to use CreationTime - this will check the type and choose the field -
      Dim sDate As Date
      If objVariant.Class = olMail Then
      sDate = objVariant.SentOn
      ElseIf objVariant.Class = olReport Then
      sDate = objVariant.CreationTime
      Else
      GoTo NextItem
      End If
      intDateDiff = DateDiff("d", sDate, Now)

    2. Diane Poremsky

      BTW, you don't want to exit the sub in the Else line, you want to use Goto to skip down to the Next to keep the macro running.
      Else
      GoTo NextItem
      End If

      NextItem:
      Next

    3. Diane Poremsky

      As an FYI, I added another macro to the page that uses Select Case to move items - you can also set different values for the age, based on item type. It's at the end of the article.

  24. Karen

    Hi Diane, Great work & thanks for your tremendous support :)
    I've been using the CASE statement to move as per your instructions, is there a way to adapt that to also move based on email address?
    I've tried using the same structure but it just doesn't work. I'm sure it's because I can't get the object right with the first CASE select.

    Ideally I'd want to have "object" as well as a 2nd CASE for email address.

    CASE obj.senderemailaddress
    if email = contractor @ mail then
    sAge = 120

    if email = newsletter @ mail then
    sAge 3
    End Case

    This way I can always leave ongoing emails in the inbox, project negotiations etc until the project is complete, then move them and then remove the CASE line for them.

    Is this possible?

    Cheers,
    Karen
    (MrsAdmin on the Forum)

    1. Diane Poremsky

      The thread is here - http://forums.slipstick.com/threads/91517-modifying-macro-moveagedmail-2-use-categories-to-as-variable/

      Case statements are set up like
      Select Case obj.senderemailaddress
      Case contractors@domain.com
      sAge = 120
      Case nbewsletters@domain.com
      sAge = 3
      Case else
      sAge = 50
      End case

  25. Glenn Case

    Diane:
    I have been using this for several months & today ran into an issue. I traced it to the statement
    intDateDiff = DateDiff("d", objVariant.SentOn, Now)
    This was reporting that the object did not support the property. The message in question was a microsoft Outlook-generated "Undeliverable" message. I got around this by adding the following line just before the offending statement:
    If Left(objVariant, 14) = "Undeliverable:" Then GoTo SkipIt

    where SkipIt is a lable ahead of the Next statement.

    I'm curious as to why this suddenly became a problem; I've had other Undeliverable messages in the past & I don't recall any such issues. Do you have any ideas?

    BTW, I appreciate your tips here. Are you aware of any good resources for learning Outlook VBA? I do quite a bit with Excel, but Outlook has been a bit of a challenge.

    1. Diane Poremsky

      I have no idea why it suddenly because an issue. For learning vba, Outlookcode.com has tutorials as does MSDN.

  26. Glenn Case

    THanks!

  27. Sorin

    Hello Diane,

    I am trying to use your script to move messages older tun 30 days from "Sent Items" to "Deleted Items" on Outlook 2010.

    Also i will like to run the script on a certain day of the month.
    How can i modify the script to achieve my task?

    Thank you.

    1. Diane Poremsky

      Change the source and destination to:
      Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderSentMail)
      Set objDestFolder = objNamespace.GetDefaultFolder(olFolderdeleteditems)

      To run it on a certain day of the month automatically, you need to use a task or appointment reminder. See http://www.slipstick.com/outlook/tasks/open-webpage-task-reminder-fires/ for details. Remove the code that loads IE and just enter the macro name that you want to run.

  28. Sorin

    Hello Diane,

    Thank you very much for your support. I changed the code as per your suggestion and it is working 99.9%. It moves all the emails older than 30 days from the "Sent Items" in to "Deleted Items"; however it leaves behind the "Calendar Meetings" and "Tasks".

    Is there a way to move those items also?

    Appreciate your support.

    Sorin

    1. Diane Poremsky

      That's because this: If objVariant.Class = olMail Then tells it to look for mail. You can remove that line and the corresponding End If, if you want to move everything.

  29. Michael Muselík (@MichaelMuselik)

    Hi, I would like to modify macro to be relatively addressed not absolutely. That means, move older messages ti the folder Archive (for example) in the current data file. I have used more data files and I would like move these messages in the current data file to the folder Archive.

    Thnx Michael

    1. Diane Poremsky

      You'd adjust these lines - use Set objSourceFolder = Application.ActiveExplorer.CurrentFolder if you want to run it on the selected folder and change the destination to the desired destination.

      Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)

      Set objDestFolder = objNamespace.Folders("Archive").Folders("Inbox")

  30. Ed

    Hi Diane

    Thanks for this, very insightful. Quick question. I wanted to ato flag(perhaps colour) all emails which have not been replied to within 23 hours of being received. I also wanted to auto flag all emails which had been received, replied to within that timeframe but were still in the inbox(for whatever reason)
    Is this possible in outlook 2007?

    Cheers

    1. Diane Poremsky

      I think you can do it, but will need to use propertyAccessor, specifically, you'd look for the last verb executed then get the time.

  31. kyaa21

    Hello Diane,

    Your macro was extremely helpful for me, as our company has put a 6 month stipulation on our emails. We can move them to a retention folder, and this macro allows me to do that swiftly. However, I do have a question. My retention folder is not part of my inbox, but my inbox has various subfolders. I can write the macro to pick a specific subfolder to move, but is it possible to write the macro so that it moves everything in my inbox + all my subfolders without having rewrite it with a specific folder each time?

    Much thanks! Kit

    1. Diane Poremsky

      You can do that, you need a function that goes though each folder. I'll see if i can find the function.

    2. John

      Were you able to find this function? I too would like for it to read multiple folders and move old mail to a subfolder of the read folder

    3. Diane Poremsky

      I haven't had time yet, i had to take some time off for a family emergency then went on vacation. Now I need a vacation from vacation. :)

  32. John

    How can you change from the inbox folder to another folder that is not a subfolder of it?
    I imagine this line needs changed but not sure what to change it to:
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)

    Any ideas?

    1. Diane Poremsky

      Yes, that is what needs to be changed to use another folder. for one at the same level as the defaults, use parent.folders:

      Set objSourceFolder = Session.GetDefaultFolder(olFolderInbox).Parent._
      Folders("folder name")

      http://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/

  33. Adam

    Hi there, thanks for this post. I have a slightly unique scenario. I need to check company emails on my iphone as well as at work. When checking on my phone its a hassle to browse to each subfolder that I've created under my inbox. Is there a way to modify this script so that it uses existing Outlook rules to move messages from my Inbox after one day to these subfolders. So for example all my mail arrives in my inbox so that I can easily check it on my phone. Then after the message has reached 1 or 2 days old, the script movies it to its specific subfolder depending on rules that I've set up in Outlook already. I have about 20 subfolders that I use. Thanks!

    1. Diane Poremsky

      Sure. You can change the date so it moves day old mail. But unless there is a fairly simple way to know which messages get filed where, it might be easier to use Run a script rules to trigger the age macro and set the folders. Or use an addin called Auto-Mate that can do this (and more).

  34. Douglas

    what code would i use if i wanted to have it move ALL mail in ALL sub folders? Private Sub Application_Startup()
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim lngMovedItems As Long
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String

    '''''''''' '''''''''' '''''''''' ''''''''''
    '''''''''' Inbox Folder ''''''''''
    '''''''''' '''''''''' '''''''''' ''''''''''

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)

    ' use a subfolder under Inbox
    Set objParent = Session.GetDefaultFolder(olFolderInbox)
    Set objManaged = objParent.Parent.Folders("Managed Folders")
    Set objDestFolder = objManaged.Folders("7 Year Retention")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)
    DoEvents
    If objVariant.Class = olMail Then

    intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    ' I'm using 60 days, adjust as needed.
    If intDateDiff > 60 Then

    objVariant.Move objDestFolder

    'count the # of items moved
    lngMovedItems = lngMovedItems + 1

    End If
    End If
    Next

    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s) From your Inbox ."
    Set objDestFolder = Nothing
    end sub

    I know i need to change this line below:
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)

    So for the example i have about 30 "sub folders" under my inbox. What would i put in place of Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox) to have it look in ALL the subfolders of Inbox ?

    Below is a full copy of the code i'm useing. I have it moving my inbox, sent mail, and i need to have it do subfolders under the main folder? I have several like this

    inbox > 30 sub folders
    vendors > 10 sub folders

    I figure that has to be a better way than to type the code over and over again....

    [ FULL CODE ]
    Private Sub Application_Startup()
    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim lngMovedItems As Long
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String

    '''''''''' '''''''''' '''''''''' ''''''''''
    '''''''''' Inbox Folder ''''''''''
    '''''''''' '''''''''' '''''''''' ''''''''''

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)

    ' use a subfolder under Inbox
    Set objParent = Session.GetDefaultFolder(olFolderInbox)
    Set objManaged = objParent.Parent.Folders("Managed Folders")
    Set objDestFolder = objManaged.Folders("7 Year Retention")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)
    DoEvents
    If objVariant.Class = olMail Then

    intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    ' I'm using 60 days, adjust as needed.
    If intDateDiff > 60 Then

    objVariant.Move objDestFolder

    'count the # of items moved
    lngMovedItems = lngMovedItems + 1

    End If
    End If
    Next

    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s) From your Inbox ."
    Set objDestFolder = Nothing

    '''''''''' '''''''''' '''''''''' ''''''''''
    '''''''''' Sent Mail Folder ''''''''''
    '''''''''' '''''''''' '''''''''' ''''''''''

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderSentMail)

    ' use a subfolder under Inbox
    Set objParent = Session.GetDefaultFolder(olFolderInbox)
    Set objManaged = objParent.Parent.Folders("Managed Folders")
    Set objDestFolder = objManaged.Folders("7 Year Retention")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)
    DoEvents
    If objVariant.Class = olMail Then

    intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    ' I'm using 7 days, adjust as needed.
    If intDateDiff > 60 Then

    objVariant.Move objDestFolder

    'count the # of items moved
    lngMovedItems = lngMovedItems + 1

    End If
    End If
    Next

    ' Display the number of items that were moved.
    MsgBox "Moved " & lngMovedItems & " messages(s) From your Sent Mail."
    Set objDestFolder = Nothing
    End Sub
    [ END CODE ]

    1. Diane Poremsky

      You need to loop through the folders. I have two samples - http://www.slipstick.com/developer/print-list-of-outlook-folders/ and http://www.slipstick.com/developer/saving-messages-to-the-hard-drive-using-vba/ that show how to loop through subfolders.

  35. Murali Krishna

    I have the code like below for moving aged mails to pst for inbox & sent items
    I wanted same thing needs to happen for inbox sub folders around 50 folders

    Public lngMovedMailItems, lngMovedMailItems1, lngMovedMailItems2

    Sub Application_Startup()

    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.Folders("xxx@xxx.com").Folders("Inbox")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)
    DoEvents
    If objVariant.Class = olMail Or objVariant.Class = olMeetingRequest Then
    Debug.Print objVariant.SentOn
    intDateDiff = DateDiff("d", objVariant.SentOn, Now)
    If intDateDiff > 30 Then
    strDestFolder = "Old Mails Pst"
    Set objDestFolder = objNamespace.Folders(strDestFolder).Folders("Inbox")
    objVariant.Move objDestFolder
    lngMovedMailItems = lngMovedMailItems + 1
    Set objDestFolder = Nothing
    End If
    End If
    Next

    Call Application_Startup_Sentitems

    End Sub

    Sub Application_Startup_Sentitems()

    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.Folders("xxx@xxx.com").Folders("Sent Items")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)
    DoEvents
    If objVariant.Class = olMail Or objVariant.Class = olMeetingRequest Then
    Debug.Print objVariant.SentOn
    intDateDiff = DateDiff("d", objVariant.SentOn, Now)
    If intDateDiff > 30 Then
    strDestFolder = "Old Mails Pst"
    Set objDestFolder = objNamespace.Folders(strDestFolder).Folders("Sent Items")
    objVariant.Move objDestFolder
    lngMovedMailItems1 = lngMovedMailItems1 + 1
    Set objDestFolder = Nothing
    End If
    End If
    Next

    lngMovedMailItems2 = lngMovedMailItems1 + lngMovedMailItems

    MsgBox "Sent Items Mails Moved " & lngMovedMailItems2 & " messages(s)."

    End Sub

    for each and every folders we cannot define functions right!!!!!!!!!!!!!!!!!

    Any help??????

    1. Diane Poremsky

      why are you using a startup macro? you need to get the folder path (using one of the samples i suggested or similar code) as use the path for the source folder.

      where do you want the messages moved to?

    2. Diane Poremsky

      This is a really rough version of what you need - it doesn't maintain the folder path in the 'old' folder, but should give you an idea of how to do it.

      Sub ProcessFolder()
      Dim objDestFolder As Outlook.MAPIFolder
      Dim objSourceFolder As Outlook.folder
      Dim objArchiveFolder As Outlook.folder
      Dim olStartFolder As Outlook.MAPIFolder

      Dim i As Long
      Dim olNewFolder As Outlook.MAPIFolder
      Dim olTempFolder As Outlook.MAPIFolder
      Dim olTempFolderPath As String
      ' Loop through the items in the current folder.

      Set olStartFolder = Session.PickFolder
      If Not (olStartFolder Is Nothing) Then
      For i = olStartFolder.Folders.Count To 1 Step -1

      Set olTempFolder = olStartFolder.Folders(i)

      ' do whatever
      Set objSourceFolder = olTempFolder
      Debug.Print "source " & objSourceFolder.Name
      ' use a subfolder under Inbox

      Set objArchiveFolder = Session.GetDefaultFolder(olFolderInbox).Parent.Folders("Old")
      On Error Resume Next
      Set objDestFolder = objArchiveFolder.Folders(olTempFolder.Name)
      Debug.Print "dest " & objDestFolder

      If objDestFolder Is Nothing Then
      Set objDestFolder = objArchiveFolder.Folders.Add(olTempFolder.Name)
      End If

      For intCount = objSourceFolder.Items.Count To 1 Step -1
      Set objVariant = objSourceFolder.Items.Item(intCount)
      DoEvents
      If objVariant.Class = olMail Then

      intDateDiff = DateDiff("d", objVariant.SentOn, Now)

      ' I'm using 7 days, adjust as needed.
      If intDateDiff > 7 Then

      objVariant.Move objDestFolder

      'count the # of items moved
      lngMovedItems = lngMovedItems + 1

      End If
      End If
      Next

      Set objDestFolder = Nothing

      Next
      ' Loop through and search each subfolder of the current folder.
      For Each olNewFolder In olStartFolder.Folders

      'Don't need to process the Deleted Items folder
      If olNewFolder.Name <> "Deleted Items" Or olNewFolder.Name <> "Old" Then
      olNewFolder
      End If

      Next
      End If

      Set objSourceFolder = Nothing
      Set objArchiveFolder = Nothing
      End Sub

  36. Haizhou

    Hi Diane,

    Thanks for the coding, It is very good starting point for Outlook addon. I am not sure if this had been covered? How to move the emails around with POP3 accounts. I have several email accounts, how to deal with that. Will the module will be trigger after I send the reply email or I have to manually trigger it?

    1. Diane Poremsky

      The account type doesn't matter - you just need to call the folders - this calls the default inbox and a subfolder under the inbox. You can just as easily use a selected folder as the starting point or use a specific folder in another data file.
      Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
      Set objDestFolder = objSourceFolder.Folders("Old")

      instructions for using other folders is here - http://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/

  37. Haizhou

    Hi Diane,

    It is a great starting point for Outlook addons. I am wondering if following two topic covered 1) What if I have more than one accounts? 2) how can I do POP3 account?

    many thanks,

    1. Diane Poremsky

      POp account won't be a problem - to use it with multiple accounts you need to set the default folder to the other accounts. If you want it to apply to all accounts, you need to reset the default folder to the next account.

      This line tells it where to look:
      Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
      you'd need to use getfolderpath function here http://www.slipstick.com/developer/working-vba-nondefault-outlook-folders/
      with
      Set objSourceFolder = GetFolderPath("New PST\Test Cal").Items

      Something like this, with two macros - one to set the strings and call the macro that does all of the work.

      public sub RunMacro()
      Set objSourceFolder = GetFolderPath("New PST\Test Cal").Items
      MoveAgedMail
      Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
      MoveAgedMail
      End sub

  38. Daniel Pham

    Hi Diane,

    Thank for providing this information its been very helpful!

    I copied your macro from your first example of how to move old email to a different folder. It seems to work but and messages are moving but I get a debug message that highlights this piece "objVariant.Move objDestFolder". I'm not sure what I did wrong or how to fix this error. I'm using Outlook 2007 and here is the macro:

    Sub MoveAgedMail(itm As Outlook.MailItem)

    Dim objOutlook As Outlook.Application
    Dim objNamespace As Outlook.NameSpace
    Dim objSourceFolder As Outlook.MAPIFolder
    Dim objDestFolder As Outlook.MAPIFolder
    Dim objVariant As Variant
    Dim lngMovedItems As Long
    Dim intCount As Integer
    Dim intDateDiff As Integer
    Dim strDestFolder As String

    Set objOutlook = Application
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    Set objSourceFolder = objNamespace.GetDefaultFolder(olFolderInbox)
    Set objDestFolder = objSourceFolder.Folders("Aged Emails > 365")

    For intCount = objSourceFolder.Items.Count To 1 Step -1
    Set objVariant = objSourceFolder.Items.Item(intCount)

    DoEvents

    If objVariant.Class = olMail Then

    intDateDiff = DateDiff("d", objVariant.SentOn, Now)

    If intDateDiff > 180 Then

    objVariant.Move objDestFolder

    lngMovedItems = lngMovedItems + 1

    End If
    End If
    Next

    End Sub

    Any help to get this corrected would be so greatly appreciated.

    1. Diane Poremsky

      What does the error message say? That line moves messages and it either can't find the folder or can't move the message. Do you have report messages, such as read receipts, or meeting requests that it is trying to move?

  39. David Kellie-Smith

    How to get MoveAgedMail to start in right mailbox

    I have two mailboxes in my Oulook 2013
    1) Lets call it "david1234@outlook.com" accessed via EAS
    2) "DavidArchive" this is a pst file built up over years. Its only purpose it to be a store of old emails. The pst file sits on my hard drive. It does not access the internet and only gets added to if I archive mail from my no 1) mailbox

    My problem is that the MoveAgedMail macro insists on working in the Archvive mailbox. It does a great job moving anything over 7 days old from archive/inbox to archive/inbox/old.

    In account settings the david1234@outlook.com OST file is shown as default.

    I would be so grateful for ideas on how to make the macro work in the No 1) mailbox

    Many thanks

    David

  40. Gaurav Khanna

    Hi Guru :-)

    Please can you help me with a code that can auto forward all email in a folder to a particular email ID if not replied in 7 days and to another email id if remained unreplied for 14 days.

    Please any help help is highly appreciable

    1. Gaurav Khanna

      Thanks a lot Diane for your help. I tried and getting a debug error in the following:

      If objVariant.Class = olMail Then

      Please can you help. I am looking forward to run this rule only on a particular mailbox. Its a kind of generic mailbox.

    2. Gaurav Khanna

      I tried it, but now nothing happenes. And i can confirm, there arent any receipts or invites in it. So, I am wondering shall I try it on a particular folder of the mailbox, or on the whole mailbox, what do you suggest.

Leave a Reply

If the Post Comment button disappears, press your Tab key.

This site uses XenWord.