I'm using your Move aged email macro. I tweaked it a little so that instead of moving all of the mail to one folder I have it going to folders based on the sender's name. Now what I would like to do is, when the macro looks for the sender's name if there is not a folder, one will be created.
The following two macros will move the messages to a folder named for the sender, creating the folder if it does not exist. The first macro works on selected messages in any folder, moving the messages to subfolders under the current folder. The second macro is the one Joel tweaked and needed help with the code to create the folder.
Creating a new folder is just a couple of lines. By using On Error Resume Next, you can set the folder variable and next line runs if an error is encountered. This is important because an error will be triggered when you try to set the destination folder to a folder that doesn't exist. The next lines tell Outlook to create the folder if it doesn't exist.
On Error Resume Next Set objDestFolder = objSourceFolder.Folders(sSenderName) If objDestFolder Is Nothing Then Set objDestFolder = objSourceFolder.Folders.Add(sSenderName) End If
File selected messages by sender's name
While I'm not a big fan of filing messages in hundreds of folders, I can see the value in filing some messages. This version of the macros works on the selected message(s) and creates a subfolder in the current folder.
Public Sub MoveSelectedMessages() Dim objOutlook As Outlook.Application Dim objNamespace As Outlook.NameSpace Dim objDestFolder As Outlook.MAPIFolder Dim objSourceFolder As Outlook.Folder Dim currentExplorer As Explorer Dim Selection As Selection Dim obj As Object 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 currentExplorer = objOutlook.ActiveExplorer Set Selection = currentExplorer.Selection Set objSourceFolder = currentExplorer.CurrentFolder For Each obj In Selection Set objVariant = obj If objVariant.Class = olMail Then intDateDiff = DateDiff("d", objVariant.SentOn, Now) ' I'm using 40 days, adjust as needed. If intDateDiff > 40 Then sSenderName = objVariant.SentOnBehalfOfName If sSenderName = ";" Then sSenderName = objVariant.SenderName End If On Error Resume Next ' Use These lines if the destination folder is not a subfolder of the current folder ' Dim objInbox As Outlook.MAPIFolder ' Set objInbox = objNamespace.Folders("alias@domain.com"). _ Folders("Inbox") ' or whereever the folder is ' Set objDestFolder = objInbox.Folders(sSenderName) Set objDestFolder = objSourceFolder.Folders(sSenderName) If objDestFolder Is Nothing Then Set objDestFolder = objSourceFolder.Folders.Add(sSenderName) End If objVariant.Move objDestFolder 'count the # of items moved lngMovedItems = lngMovedItems + 1 Set objDestFolder = Nothing End If End If Err.Clear Next ' Display the number of items that were moved. MsgBox "Moved " & lngMovedItems & " messages(s)." Set currentExplorer = Nothing Set obj = Nothing Set Selection = Nothing Set objOutlook = Nothing Set objNamespace = Nothing Set objSourceFolder = Nothing End Sub
File aged messages by sender's name
This version of the macro moves messages to an Inbox subfolder named for the sender. It looks for the display name, and if a folder does not exist, it creates it. If the sender uses different email clients, the messages may be filed in several folders. Using the sender's email address would eliminate this problem, but make it harder to know who each folder is for.
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) 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 40 days, adjust as needed. If intDateDiff > 40 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 sSenderName = objVariant.SentOnBehalfOfName If sSenderName = ";" Then sSenderName = objVariant.SenderName End If On Error Resume Next Set objDestFolder = objSourceFolder.Folders(sSenderName) If objDestFolder Is Nothing Then Set objDestFolder = objSourceFolder.Folders.Add(sSenderName) End If objVariant.Move objDestFolder 'count the # of items moved lngMovedItems = lngMovedItems + 1 Set objDestFolder = Nothing End If End If Next ' Display the number of items that were moved. MsgBox "Moved " & lngMovedItems & " messages(s)." Set objOutlook = Nothing Set objNamespace = Nothing Set objSourceFolder = Nothing End Sub
File by Year
This code snippet shows how to file messages by year, moving only those messages that are older than a year.
Dim intYear As String If objVariant.Class = olMail Then intDateDiff = DateDiff("d", objVariant.ReceivedTime, Date) Debug.Print Date & " " & intDateDiff If intDateDiff > 365 Then intYear = Year(objVariant.ReceivedTime) Debug.Print objVariant.Subject & "--" & intYear On Error Resume Next Set objDestFolder = objSourceFolder.Folders(intYear) ' Debug.Print objDestFolder If objDestFolder Is Nothing Then Set objDestFolder = objSourceFolder.Folders.Add(intYear) End If objVariant.Move objDestFolder 'count the # of items moved lngMovedItems = lngMovedItems + 1 Set objDestFolder = Nothing End If Err.Clear End If Next
File Messages as they arrive
This ItemAdd macro runs as messages hit the default inbox and file messages to a subfolder of the Inbox, by the sender's display name. To use SMTP address, change SenderName to SenderEmailAddress, note however, that if you use Exchange server, you will need to get the Exchange SMTP.
Option Explicit Private objNS As Outlook.NameSpace Private WithEvents objItems As Outlook.Items Private Sub Application_Startup() Dim objWatchFolder As Outlook.Folder Set objNS = Application.GetNamespace("MAPI") 'Set the folder and items to watch: Set objWatchFolder = objNS.GetDefaultFolder(olFolderInbox) Set objItems = objWatchFolder.Items Set objWatchFolder = Nothing End Sub Private Sub objItems_ItemAdd(ByVal Item As Object) Dim objParentFolder As Outlook.Folder Dim objDestFolder As Outlook.Folder Dim objVariant As Variant Dim sSenderName As String Set objVariant = Item Set objParentFolder = objNS.GetDefaultFolder(olFolderInbox) If objVariant.Class = olMail Then sSenderName = objVariant.SentOnBehalfOfName If sSenderName = ";" Then sSenderName = objVariant.SenderName End If On Error Resume Next Set objDestFolder = objParentFolder.Folders(sSenderName) If objDestFolder Is Nothing Then Set objDestFolder = objParentFolder.Folders.Add(sSenderName) End If objVariant.Move objDestFolder Set objDestFolder = Nothing End If 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:
- Right click on Project1 and choose Insert > Module
- Copy and paste the macro into the new module.
More information as well as screenshots are at How to use the VBA Editor
Hi Diane,
Thanks for your perfect work, the "File aged messages by sender's name" script does help me a lot for filing mails.But, can I have your advise that how I could change the destination folder from "Inbox" to some kind like: "Archive" which would be the same level with "Inbox"?
Hello Diane, Could you please help in modifying the following script, so that it creates a subfolder with the sender name in the 'domain' folder? For e.g email from test@domain.com, folders will be domain.com/test/ This will be very helpful for many people. Public Sub MoveSelectedToDomain() Dim objOutlook As Outlook.Application Dim objNamespace As Outlook.NameSpace Dim objDestFolder As Outlook.MAPIFolder Dim objSourceFolder As Outlook.Folder Dim currentExplorer As Explorer Dim Selection As Selection Dim obj As Object 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 currentExplorer = objOutlook.ActiveExplorer Set Selection = currentExplorer.Selection Set objSourceFolder = currentExplorer.CurrentFolder For Each obj In Selection Set objVariant = obj If objVariant.Class = olMail Then intDateDiff = DateDiff("d", objVariant.SentOn, Now) ' I'm using 40 days, adjust as needed. If intDateDiff >= 0 Then sSenderName = Right(objVariant.SenderEmailAddress, Len(objVariant.SenderEmailAddress) - InStr(objVariant.SenderEmailAddress, "@")) If sSenderName = ";" Then sSenderName = objVariant.SenderName End If On Error Resume Next Set objDestFolder = objNamespace.Folders("OutlookEmail").Folders(sSenderName) 'Set objDestFolder = objDestFolder.Folders(sSenderName) If objDestFolder Is Nothing Then Set objDestFolder = objNamespace.Folders("OutlookEmail").Folders.Add(sSenderName) End If objVariant.Move objDestFolder 'count the # of items moved lngMovedItems = lngMovedItems + 1 Set objDestFolder… Read more »
Any way to sort in folders by conversation
Is their any way to have it create the folder by the domain of the email?
Yes - you'd change this line to use the domain: sSenderName = objVariant.SentOnBehalfOfName
sSenderName = Right(objVariant.SenderEmailAddress, Len(objVariant.SenderEmailAddress) - InStr(objVariant.SenderEmailAddress, "@"))
Hi Diane,
I know I'm a few years late, but I absolutely love your macro of filing emails into senders folder names, and want to thankyou deeply.
I'm having trouble getting the code to recognise when I have moved the folder to a subfolder. I've tried all the suggestions in the comments but to no luck.
Ideally Id like to file emails to the folder irrespective of where it is in the folder tree. That might be two or 3 sub fodders deep from the Inbox level. Any help would be really, really appreciated. Thankyou kindly :)
I have a macro that looks up a folder - but i have not used it nested folders - all of the folders were under Inbox\Clients\. I'll need to work it into in the macro - i believe you'd replace Set objDestFolder = objSourceFolder.Folders(sSenderName) with FindFolder
(Actually, i borrowed it from Michael Bauer - http://vboffice.net/en/developers/find-folder-by-name)
Public Sub FindFolder()
Dim Name$
Dim Folders As Outlook.Folders
Dim Folder As Outlook.MAPIFolder
Set m_Folder = Nothing
m_Find = ""
Name = "*" & strCode
If Len(Trim$(Name)) = 0 Then Exit Sub
m_Find = Name
m_Find = LCase$(m_Find)
Set Folder = Session.GetDefaultFolder(olFolderInbox).Parent.Folders("Clients")
LoopFolders Folder.Folders
End Sub
Private Sub LoopFolders(Folders As Outlook.Folders)
Dim Folder As Outlook.MAPIFolder
Dim F As Outlook.MAPIFolder
Dim Found As Boolean
If SpeedUp = False Then DoEvents
For Each F In Folders
Found = (LCase$(F.Name) Like m_Find)
If Found Then
Set m_Folder = F
Exit For
Else
LoopFolders F.Folders
If Not m_Folder Is Nothing Then Exit For
End If
Next
End Sub
Hi Diane,
I wanted to know how this could be modified to accomodate distribution lists or recipients. The short of it is this. I work in an environment where the are literally a few hundred emails that flood my inbox per day. I would like to move everything back into my inbox as I have something conflicting with my rules. However, some emails that come in are sent to a distro and some are sent directly to me. The Senders of the emails can come from a distribution group or from an individual.
For example: emails for the Help Desk come from individuals. However when there is a major incident and we email out the email comes from a distribution group named incident reporting.
I have mapped out the folders in a word document - and figure that I would need a Case statement or nested IF ELSE statements, but do not know how to access different aspects of the Mail Item Object.
Any insights would be much appreciated.
Thanks
Jeremy
Diane, when I first found your VBA script over 2 ½ years ago, I thought it was heaven sent. I don’t VBA and my current position doesn’t allow me the opportunity to learn what I need, just come up with ideas. I finally ran your script a year later and it produced 500+ folders, which was crazy. Any chance you can create a folder by domain name and then another folder in that folder by the sender from that domain. That would cut down my folders by 65-75%. Another idea, since some domains are just letters (ex. bcad.org, for Bexar County Appraisal District) is it possible for it to look at a table that translates a domains letters to a more clear description and create a folder from that? If it don’t find the domain name in the table it doesn’t do anything, indicating to me that I have to modify the table. Hope you can help. This is just for personal use.
Yeah, it creates a crazy number of folders - i made the mistake of testing it on my inbox. Ouch. Moving everything back was a pita. :)
It would be possible to file by by domain then by alias or address - you need to create the domain folder then check for the alias. (I don't have any samples that do it) - or you could file by domain then sort or group by sender, to reduce the number of folders.
I've tested the both macro (aged message and selected messages) on Office 365 (version 2016) and I have an issue. The folders are created based on senders names but the messages associated to the senders name remain at their original location and are not moved in the newly created folders. Also I would like to be able to first create a folder of the domain and then subfolders of the senders of that domain. Also would it be possible to remove the empty space at the beginning of the folder name if any in order sort properly folders even if the sender name start with a space (space would be removed in folder name). Could to send me the sample of code required to fixe the issue and the other 2 enhancements requested ?
Removing the space should be fairly easy - use the Trim function. replace sSenderName with Trim(sSenderName) in the line that creates the folder.
Creating domain folders then adding the subfodlers would be a bit more complicated (do-able but complicated). You need to get the domain name then create the folder and set it as the parent for the destination folder. I don't have any sample code that does this, only sample code that gets the domain name.
strDomain = Right(objMail.SenderEmailAddress, Len(objMail.SenderEmailAddress) - InStr(objMail.SenderEmailAddress, "@"))