Mark Sent Items as Read After Copying with a Rule

Last reviewed on May 8, 2014   —  31 comments

Fulvio needs to use rules to move sent messages, but the sent items are not marked read when they are copied to other folders.

I’ve set up a rule for copying any message I send out to a local outbox folder (rather than the one on remote server). Therefore, I’ve uncheck the standard option “save a copy of sent messages”, as I don’t need to duplicate them remotely. Everything works fine: I have no longer remote copies of sent emails, and I have the local ones, but these latter are now bolded as unread. So, I’d like to set my custom rule as: copy sent messages to the local outbox AND mark them as read. Yet it seems to be impossible….

It's not impossible to do, but it won't work with Rules. "After Sending" rules don't support custom actions, run a script, or marking items as read. However, you can use VBA to mark sent items read.

Because the sent item is not in the default data file, you'll need to use the code at Use a folder in another pst or Mailbox to identify the data file. Paste it and the code below into the ThisOutlookSession module in the VB Editor.

Change this line: Set Items = GetFolderPath("New PST\Sent Items").Items to reflect the data file name in the folder list and the folder name you are moving the sent item to.

Code Sample: Mark Moved Messages as Read

To test this code, click in the Application_Startup module and press Run to start it without restarting Outlook. Don't forget to get the GetFolderPath function from Use a folder in another pst or Mailbox.


Private WithEvents Items As Outlook.Items

Private Sub Application_Startup()
   Set Items = GetFolderPath("New PST\Sent Items").Items
End Sub

Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
End Sub

Mark deleted items read automatically

To mark messages read as they are moved into a folder within the mailbox, such as the deleted items folder, use the following code sample.

To use the junk mail folder, use
Set Items = Ns.GetDefaultFolder(olFolderJunk).Items

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
   
End Sub

Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
End Sub

Move sent messages using VBA

This code sample moves the sent messages using VBA, rather than a rule.

If the folder you are moving the sent items to is in a different pst file, you'll need the GetFolderPath function at Use a folder in another pst or Mailbox.

Private WithEvents Items As Outlook.Items

Private Sub Application_Startup()
Set Items = Session.GetDefaultFolder(olFolderSentMail).Items

End Sub

Private Sub Items_ItemAdd(ByVal Item As Object)
    Set MovePst = GetFolderPath("NewPST\Sent Items")
    Item.UnRead = False
    Item.Move MovePst
End Sub

More Information

More VBA samples that mark moved message as read are at:
Marking Sent Items as Read How to mark messages read when they are moved to multiple folders (WindowsITPro)
E-Mail: Mark as read Mark as read when moved to a subfolder of the Inbox (vboffice.net)
Mark mails as Read automatically in Deleted Items Folder after deleting mails from any folder (outlookcode.com)

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.

31 responses to “Mark Sent Items as Read After Copying with a Rule”

  1. Claire

    Good to know--though I must say that Gmail's "mark as read" option for foldered mail is a bit quicker than VBA ;)

    1. Diane Poremsky

      If you use rules to move mail, you can mark read using rules - but Outlook only lets you copy mail after sending and doesn't offer a mark as read option for it. (Don't ask me why - I think it should.)

  2. Fulvio

    Dear Diane,
    said that I'm quite far from being a VBA expert (in fact, this is my very first time), I tried to write down in sequence, under ThisOutlookSession module, what you indicated, following the instructions for replacing the string as well. As soon as I try to run the module to test it, I got an error message (translating from italian): "Invalid attribute within Sub or Function". could you help me further? Thanks
    Hereafter what is currently in my editor:

    Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
    Dim oFolder As Outlook.Folder
    Dim FoldersArray As Variant
    Dim i As Integer

    On Error GoTo GetFolderPath_Error
    If Left(FolderPath, 2) = "\\" Then
    FolderPath = Right(FolderPath, Len(FolderPath) - 2)
    End If
    'Convert folderpath to array
    FoldersArray = Split(FolderPath, "\")
    Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
    If Not oFolder Is Nothing Then
    For i = 1 To UBound(FoldersArray, 1)
    Dim SubFolders As Outlook.Folders
    Set SubFolders = oFolder.Folders
    Set oFolder = SubFolders.Item(FoldersArray(i))
    If oFolder Is Nothing Then
    Set GetFolderPath = Nothing
    End If
    Next
    End If
    'Return the oFolder
    Set GetFolderPath = oFolder
    Exit Function

    GetFolderPath_Error:
    Set GetFolderPath = Nothing
    Exit Function
    End Function

    Private WithEvents Items As Outlook.Items

    Private Sub Application_Startup()
    Set Items = GetFolderPath("Cartelle Personali\Posta Inviata").Items
    End Sub

    Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
    End Sub

    1. Diane Poremsky

      Do the colors of the text in the VBA editor more or less match the ones on the pages online? Red text is bad. Check the quotes and verify they are plain old quotes and not smart quotes.

    2. Diane Poremsky

      Oh, and also put the Function code after the other code.

  3. Fulvio

    Great! It works perfectly!
    Thanks a million.

  4. Stuart

    Hi Diane

    I got the code in to mark all the emails as read when sent from one email address and stored in a defined folder.
    Now how do I start a new project to do the same thing for the other email address and its defined folder.

    I don't know how to start a new project.

    using outlook 2007

    thanks

  5. Martins

    Hi Diane,

    I try to get this work, but it comes back with: Compile error: "Invalid attribute in Sub or Function" and marks "WithEvents Items As Outlook.Items"

    Thanks for help!

    My full code:

    Private WithEvents Items As Outlook.Items
    Private Sub Application_Startup()
    Set Items = GetFolderPath("New PST\Sent Items").Items
    End Sub
    Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
    End Sub
    Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
    Dim oFolder As Outlook.Folder
    Dim FoldersArray As Variant
    Dim i As Integer

    On Error GoTo GetFolderPath_Error
    If Left(FolderPath, 2) = "\\" Then
    FolderPath = Right(FolderPath, Len(FolderPath) - 2)
    End If
    'Convert folderpath to array
    FoldersArray = Split(FolderPath, "\")
    Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
    If Not oFolder Is Nothing Then
    For i = 1 To UBound(FoldersArray, 1)
    Dim SubFolders As Outlook.Folders
    Set SubFolders = oFolder.Folders
    Set oFolder = SubFolders.Item(FoldersArray(i))
    If oFolder Is Nothing Then
    Set GetFolderPath = Nothing
    End If
    Next
    End If
    'Return the oFolder
    Set GetFolderPath = oFolder
    Exit Function
    GetFolderPath_Error:
    Set GetFolderPath = Nothing
    Exit Function
    End Function

    1. Diane Poremsky

      Make sure you change the path here to the actual pst name folder -

      Set Items = GetFolderPath("New PST\Sent Items").Items

      and it should work (when you put the first part at the top of =ThisOutlookSession as per my other comment). You need just the code in the comment (I removed the stuff you don't need, to reduce confusion and make it easier to read.)

    2. Diane Poremsky

      Make sure you change the path here to the actual pst name folder -

      Set Items = GetFolderPath("New PST\Sent Items").Items

      and it should work (when you put the first part at the top of (ThisOutlookSession as per my other comment). You need just the code in the comment (I removed the stuff you don't need, to reduce confusion and make it easier to read.)

  6. Martins

    P.S. I try to run it for sent mails that are moved to Inbox subfolders..

    Thanks again!

    1. Diane Poremsky

      This part needs to be at the top of ThisOutlookSession.

      Private WithEvents Items As Outlook.Items
      Private Sub Application_Startup()
      Set Items = GetFolderPath("New PST\Sent Items").Items
      End Sub

      Also, you only need the GetFolderPath function from the bottom of the other page, not all of the code on the page. (I'll fix my instructions.)

  7. Chris Gilbert

    Don't know if anyone is reading this old thread, but I think if I turn off the save copy in Sent folder in Email Options and handle everything through Rules, then my Journal can't be used to save incoming and outgoing emails as entries there for record-keeping purposes which I find valuable for recreating my work for billing purposes.

    1. Diane Poremsky

      It's possible - i have not tested it with journaling, in part because the journal is broken in Outlook 2010 and sent to death row in 2013.

  8. Marek

    Hello Diane, I dont know where I am doing mistake but I cannot make this to work. I just copy/paste Martins code from September 25. where I only changed GetFolderPath to right PST folder but i am getting this error: "Compile error: Only valid object module" (Private WithEvents Items... line is in red color). In ThisOutlookSession have I insert Module or Class Module? When I try to insert Class module I am not able to test/save project...
    Please can you provide whole working code - with GetFolderPath? Thank you in advance. Marek

    1. Diane Poremsky

      Did you try pasting it in ThisOutlookSession? Double click on ThisOutlooksession on the left to open it on the right side of the editor.

  9. Marek

    No, as I wrote before, I had only insert new "Module/Class Module" Right now I try paste code as you mention but nothing is happening. "Unread" message still remain in Sent folder... No matter if I hit F5 key or Outlook was closed/reopened.

    1. Diane Poremsky

      After you paste it in ThisOutlookSession, you need to click in the Application Startup macro and press the run button - this will start the macro without actually restarting outlook.

  10. Marek

    Thank you for an answer but I did exactly what you wrote without success. Messages in Sent folder still remain marked as unread. Please can you check my full code:

    Private WithEvents Items As Outlook.Items
    Private Sub Application_Startup()
    Set Items = GetFolderPath("Personal Folders\Sent Items").Items
    End Sub
    Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
    End Sub
    Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
    Dim oFolder As Outlook.Folder
    Dim FoldersArray As Variant
    Dim i As Integer

    On Error GoTo GetFolderPath_Error
    If Left(FolderPath, 2) = "\\" Then
    FolderPath = Right(FolderPath, Len(FolderPath) - 2)
    End If
    'Convert folderpath to array
    FoldersArray = Split(FolderPath, "\")
    Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
    If Not oFolder Is Nothing Then
    For i = 1 To UBound(FoldersArray, 1)
    Dim SubFolders As Outlook.Folders
    Set SubFolders = oFolder.Folders
    Set oFolder = SubFolders.Item(FoldersArray(i))
    If oFolder Is Nothing Then
    Set GetFolderPath = Nothing
    End If
    Next
    End If
    'Return the oFolder
    Set GetFolderPath = oFolder
    Exit Function
    GetFolderPath_Error:
    Set GetFolderPath = Nothing
    Exit Function
    End Function

    1. Diane Poremsky

      It works here. Did you click in Application startup macro and click run to kick start it?

      Try adding msgbox "Working" as the first line of the itemadd macro - when the macro fires the message box will come up. That will tell us if its working.

      Private Sub Items_ItemAdd(ByVal Item As Object)
      msgbox "Working"
      Item.UnRead = False
      Item.Save
      End Sub

  11. Marek

    Once again thank you Diane for your patience, but maybe I am stupid enough because after I am hitting RunSub/UserForm(F5) button, nothing is happend. I made two screenshots of my project/outlook. If you have a time, please look at this. http://1drv.ms/1cPCjOE Maybe you will find something what I am still missing...
    Just for testing purpose i have used this guide http://msdn.microsoft.com/en-us/library/office/ff869298.aspx and message box appears correctly.

    1. Diane Poremsky

      I'm guessing its the localization that is the problem. You tried it both with the localized name and "Sent Items"?

  12. Marek

    I don't think so Diane. I've already tested it with "Sent Items" and I am getting error: Run-time error 91. http://1drv.ms/1cPCjOE

    1. Diane Poremsky

      If you are getting the when Outlook restarts or when you click in Application_Startup and click Run, it means the macro can't find the folder. Replace it with archive or one of the other names with only ASCII characters and click Run in the App Startup macro.

  13. Chris

    My code is this but it gives me " object variable or with block variable not set 91" - What is wrong?

    Private WithEvents Items As Outlook.Items
    Private Sub Application_Startup()
    Dim Items As Outlook.Items
    Set Items = GetFolderPath("C:\Users\cc580e\Desktop\Chirag - Personal Folders(1).pst\Sent Items").Items
    MsgBox "test"
    End Sub
    Private Sub Items_ItemAdd(ByVal Item As Object)
    Item.UnRead = False
    Item.Save
    End Sub
    Function GetFolderPath(ByVal FolderPath As String) As Outlook.Folder
    Dim oFolder As Outlook.Folder
    Dim FoldersArray As Variant
    Dim i As Integer

    On Error GoTo GetFolderPath_Error
    If Left(FolderPath, 2) = "\\" Then
    FolderPath = Right(FolderPath, Len(FolderPath) - 2)
    End If
    'Convert folderpath to array
    FoldersArray = Split(FolderPath, "\")
    Set oFolder = Application.Session.Folders.Item(FoldersArray(0))
    If Not oFolder Is Nothing Then
    For i = 1 To UBound(FoldersArray, 1)
    Dim SubFolders As Outlook.Folders
    Set SubFolders = oFolder.Folders
    Set oFolder = SubFolders.Item(FoldersArray(i))
    If oFolder Is Nothing Then
    Set GetFolderPath = Nothing
    End If
    Next
    End If
    'Return the oFolder
    Set GetFolderPath = oFolder
    Exit Function
    GetFolderPath_Error:
    Set GetFolderPath = Nothing
    Exit Function
    End Function

    1. Diane Poremsky

      getfolderpath path is wrong, should be the display name and folders as it appears in the folder list.

  14. Stephanie Hudson

    With the code, all new mail in my folder is being marked as read, not just the newly sent mail. How can I alter the code so that only the mail sent from myself is marked as read.

    Details:
    I'm wanting to keep conversation threads together, including sent mail. Ideally I want all this mail in my inbox until I decide I'm done with it and save it to another folder elsewhere. That is, I want all incoming mail and sent mail in the same "inbox" folder. Right now, I'm doing that in a folder directly below Outlook's inbox called "_My Inbox_".

    A. I have a rule: After I send a message, move a copy to the "_My Inbox_" folder.
    B. I have a bunch of other rules handling mail that can go to other folders or the trash.
    C. My last rule is: After a message arrives, move it to the "_My Inbox_" folder.
    D. In Mail Options, Save messages settings, I have "When replying to a message that is not in the Inbox, save the reply in the same folder" ticked (true).
    E. In Mail Options, Save messages settings, I have "Save copies of messages in the Sent Items folder" NOT ticked (false).
    -------
    What's happening is that the Sent mail is Unread.
    I tried adding a rule to mark mail from me (sent) as read, but this doesn't work as the mail just gets moved there, it doesn't actually "arrive" as the rule expects.
    -------
    F. So, I found your code and have applied it. However, now ALL mail coming to "_My Inbox_" is marked as read.

    How can I alter the code so that only the mail sent from myself is marked as read.

    1. Stephanie Hudson

      Am I putting that in the Application_Startup()? I currently have:
      Private Sub Application_Startup()
      Set Items = Session.GetDefaultFolder(olFolderInbox).Folders("_My Inbox_").Items
      End Sub

      Sorry, this is my first time with VBA in Outlook. Only used it in Excel and Access before.
      Thanks.

    2. Stephanie Hudson

      It's working now. Thank you so much for your help! I really appreciate it.

Leave a Reply

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

This site uses XenWord.