One thing that really annoys me about Outlook is that I can right click on a message and do pretty much anything I might want to do, except create a search folder.
I like to create search folders for people who hire me then when the project is finished, I delete the search folder.
Find Related is slow and not persistent. Plus, looking over the list of search folders helps me remember who I'm looking for. :)
Use VBA to create an Instant search for messages from the selected contact.
VBA to the rescue (as always!) The following code creates a search folder using either the sender's display name or email address. It's an amazingly fast search. Next on my to-do list: use VBA to replace the Activities tab.
Error # -2147219964 : Cannot create folder. is trying to tell you that the folder name exists. Use the DeleteSearchFolder macro to delete it, then recreate it. Run-time error '-2147352567 (80020009)': Array index out of bounds means you do not have an email message selected.
Create search folder for message sender macro
Open the VBA editor using Alt+F11, paste the code into the editor. Select a message and run the macro.
The current iteration works on the default Inbox (and subfolders) and Sent folder. It can easily be tweaked to use a selected contact:
Dim oMail As Outlook.ContactItem
strFilter = oMail.Email1Address
Updated March 11 2015: Results include messages sent to and from the sender which are in the Inbox (and subfolders) and Sent Items folder. The From filter looks for messages from the sender's email address; the To filter checks for both the email address and the sender's display name. The Search folder uses the Sender's name, not the email address.
Sub SearchFolderForSender() On Error GoTo Err_SearchFolderForSender Dim strFrom As String Dim strTo As String ' get the name & email address from a selected message Dim oMail As Outlook.MailItem Set oMail = ActiveExplorer.Selection.Item(1) strFrom = oMail.SenderEmailAddress strTo = oMail.SenderName If strFrom = "" Then Exit Sub Dim strDASLFilter As String ' From & To fields Const From1 As String = "http://schemas.microsoft.com/mapi/proptag/0x0065001f" Const From2 As String = "http://schemas.microsoft.com/mapi/proptag/0x0042001f" Const To1 As String = "http://schemas.microsoft.com/mapi/proptag/0x0e04001f" Const To2 As String = "http://schemas.microsoft.com/mapi/proptag/0x0e03001f" strDASLFilter = "((""" & From1 & """ CI_STARTSWITH '" & strFrom & "' OR """ & From2 & """ CI_STARTSWITH '" & strFrom & "')" & _ " OR (""" & To1 & """ CI_STARTSWITH '" & strFrom & "' OR """ & To2 & """ CI_STARTSWITH '" & strFrom & "' OR """ & To1 & """ CI_STARTSWITH '" & strTo & "' OR """ & To2 & """ CI_STARTSWITH '" & strTo & "' ))" Debug.Print strDASLFilter Dim strScope As String strScope = "'Inbox', 'Sent Items'" Dim objSearch As Search Set objSearch = Application.AdvancedSearch(Scope:=strScope, Filter:=strDASLFilter, SearchSubFolders:=True, Tag:="SearchFolder") 'Save the search results to a searchfolder objSearch.Save (strTo) Set objSearch = Nothing Exit Sub Err_SearchFolderForSender: MsgBox "Error # " & Err & " : " & Error(Err) End Sub
Search folder for All Accounts
This code sample creates a search folder in the selected account in your Outlook profile. As written, the search folder searches the Inbox, Sent Items, and Archive folder as well as the folder the selected message is in. (It also searches subfolders within those folders.)
It will work in both the default account and in secondary accounts or data files that support search folders.
Updated June 2 2021 to add the Search folder to Mail Favorites.
Sub SearchFolderForSenderAllAcct() Dim strName As String Dim strFrom As String Dim storeName As String Dim currentFolder As String Dim prompt As String ' get the name & email address from a selected message Dim oMail As Outlook.MailItem On Error Resume Next Set oMail = ActiveExplorer.Selection.Item(1) If oMail Is Nothing Then GoTo Err_SearchFolderForSender strName = oMail.SenderName strFrom = oMail.SenderEmailAddress Debug.Print strFrom, strName currentFolder = Application.ActiveExplorer.currentFolder.FolderPath currentFolder = Replace(currentFolder, "\\", "\") pos = InStr(4, currentFolder, "\") storeName = Replace(Left(currentFolder, pos), "\", "") Debug.Print pos, storeName If strFrom = "" Then GoTo Err_SearchFolderForSender Dim oStores As Outlook.Stores Dim oStore As Outlook.Store Dim oFolder As Outlook.folder Set oStores = Application.Session.Stores Debug.Print oStores.Item(storeName).DisplayName If oStores.Item(storeName).DisplayName Then Set oStore = oStores.Item(storeName) Set oFolder = oStore.GetSearchFolders.Item(strName) If Not oFolder Is Nothing Then prompt$ = "Search folder for '" & strName & "' already exists. Do you want to add it to Mail Favorites?" GoTo AddtoFavs Else End If End If Dim strDASLFilter As String ' From & To fields Const From1 As String = "http://schemas.microsoft.com/mapi/proptag/0x0065001f" Const From2 As String = "http://schemas.microsoft.com/mapi/proptag/0x0042001f" Const To1 As String = "http://schemas.microsoft.com/mapi/proptag/0x0e04001f" Const To2 As String = "http://schemas.microsoft.com/mapi/proptag/0x0e03001f" strDASLFilter = "((""" & From1 & """ CI_STARTSWITH '" & strFrom & "' OR """ & From2 & """ CI_STARTSWITH '" & strFrom & "')" & _ " OR (""" & To1 & """ CI_STARTSWITH '" & strFrom & "' OR """ & To2 & """ CI_STARTSWITH '" & strFrom & "' OR """ & To1 & """ CI_STARTSWITH '" & strName & "' OR """ & To2 & """ CI_STARTSWITH '" & strName & "' ))" 'Debug.Print strDASLFilter Dim strScope As String strScope = "'\" & storeName & "\Inbox', '\" & storeName & "\Sent Items','\" & storeName & "\Archive', '" & currentFolder & "'" ' Debug.Print strScope Dim objSearch As Search Set objSearch = Application.AdvancedSearch(Scope:=strScope, Filter:=strDASLFilter, SearchSubFolders:=True, Tag:="SearchFolder") 'Save the search results to a searchfolder objSearch.Save (strName) Set objSearch = Nothing prompt$ = "Do you want to add '" & strName & "' to Mail Favorites?" AddtoFavs: If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Add search folder to Favorites?") = vbYes Then ' continue Else Exit Sub End If 'Debug.Print oStores.Item(storeName).DisplayName Set oFolder = oStore.GetSearchFolders.Item(strName) Set objNavigationPane = Application.ActiveExplorer.NavigationPane Set objNavigationModule = objNavigationPane.Modules.GetNavigationModule(olModuleMail) Set objNavigationGroup = objNavigationModule.NavigationGroups.GetDefaultNavigationGroup(olFavoriteFoldersGroup) 'Add folder to Favorites objNavigationGroup.NavigationFolders.Add oFolder Exit Sub Err_SearchFolderForSender: MsgBox "You need to select an email message!" End Sub
Create a search folder for categories
This version of the macro creates a search folder using two categories creates a search folder using one or two categories. If there are more than two categories assigned, it uses just the first two categories (which in Outlook is the last two categories you assigned.)
If a message has more than two assigned, that message will be found as the search filter looks for category1 and category2; we can't tell it to only use those two (and ignore if more than two categories).
In the example in this screen shot, the search folder that is created will find all messages with the first categories.
Sub SearchFolderForCategories() On Error GoTo Err_SearchFolderForSender Dim strCat1 As String Dim strCat2 As String ' get the name & email address from a selected message Dim oMail As Outlook.MailItem Set oMail = ActiveExplorer.Selection.Item(1) arr = Split(oMail.Categories, ",") ' if only one category If UBound(arr) = 0 Then strCat1 = arr(0) strDASLFilter = "(" & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat1 & "')" End If If UBound(arr) > 0 Then ' Check for Category 'get first 2 For i = 0 To UBound(arr) Debug.Print UBound(arr) strCat1 = arr(0) strCat2 = Trim(arr(1)) Next strDASLFilter = "(" & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat1 & "' AND " & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat2 & "')" End If Debug.Print strDASLFilter Dim strScope As String strScope = "'Inbox', 'Sent Items'" Dim objSearch As Search Set objSearch = Application.AdvancedSearch(Scope:=strScope, Filter:=strDASLFilter, SearchSubFolders:=True, Tag:="SearchFolder") 'Save the search results to a searchfolder objSearch.Save (oMail.Categories) Set objSearch = Nothing Exit Sub Err_SearchFolderForSender: MsgBox "Error # " & Err & " : " & Error(Err) End Sub
Category Search folder for non-default account
This code sample creates a search folder in the selected secondary account in your Outlook profile. As written, the search folder searches the Inbox, Sent Items, and Archive folder as well as the folder the selected message is in. (It also searches subfolders within those folders.)
This code will check for one or both of first two categories on the selected message.
Sub SearchFolderCategoryNonDefaultAcct() On Error GoTo Err_SearchFolderForSender Dim strCat1 As String Dim strCat2 As String ' get the name & email address from a selected message Dim oMail As Outlook.MailItem Set oMail = ActiveExplorer.Selection.Item(1) 'get the folderpath of current folder currentFolder = Application.ActiveExplorer.currentFolder.FolderPath currentFolder = Replace(currentFolder, "\\", "\") ' keep store name, not folder paths pos = InStr(4, currentFolder, "\") storeName = Replace(Left(currentFolder, pos), "\", "") Debug.Print pos, storeName Dim strDASLFilter As String arr = Split(oMail.Categories, ",") ' if only one category If UBound(arr) = 0 Then strCat1 = arr(0) strDASLFilter = "(" & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat1 & "')" End If If UBound(arr) > 0 Then ' Check for Category 'get first 2 For i = 0 To UBound(arr) Debug.Print UBound(arr) strCat1 = arr(0) strCat2 = Trim(arr(1)) Next strDASLFilter = "(" & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat1 & "' AND " & """urn:schemas-microsoft-com:office:office#Keywords""" & "= '" & strCat2 & "')" End If Debug.Print strDASLFilter Dim strScope As String strScope = "'\" & storeName & "\Inbox', '\" & storeName & "\Sent Items','\" & storeName & "\Archive', '" & currentFolder & "'" Dim objSearch As Search Set objSearch = Application.AdvancedSearch(Scope:=strScope, Filter:=strDASLFilter, SearchSubFolders:=True, Tag:="SearchFolder") 'Save the search results to a searchfolder objSearch.Save (oMail.Categories) Set objSearch = Nothing Exit Sub
Delete the Search folder
To delete the search folder you created using the code above, you can use a macro such as this one.
This is a tweaked version of the macro at (Less Than) Portable Search Folders.
Sub DeleteSearchFolder() Dim CommonViewsEID As String Dim CommonViewsEIDString As String Dim CommonViewsFolder As Folder Dim ACTable As Table Dim oRow As Row Dim SFDefinitionEID As String Dim SFDefinitionItem As StorageItem Dim strFilter As String Dim oMail As Outlook.MailItem Set oMail = ActiveExplorer.Selection.Item(1) strFilter = oMail.SenderName CommonViewsEID = Session.DefaultStore.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x35E60102") CommonViewsEIDString = Session.DefaultStore.PropertyAccessor.BinaryToString(CommonViewsEID) Set CommonViewsFolder = Session.GetFolderFromID(CommonViewsEIDString) Set ACTable = CommonViewsFolder.GetTable("[Subject] = '" & strFilter & "'", olHiddenItems) Set oRow = ACTable.GetNextRow() If (Not (oRow Is Nothing)) Then SFDefinitionEID = oRow("EntryID") Set SFDefinitionItem = Session.GetItemFromID(SFDefinitionEID) SFDefinitionItem.Delete End If End Sub
Searching other fields
You can search any Outlook field if you know the field name and filter code to use. The easiest way to find out what you need to replicate a filter is to create a filter in Outlook then check the SQL tab.
You can use the httpmail and mailheader namespace schemas for some fields, but some search queries, such as the sender's actual email address, need the mapi property tag.
The httpmail and mailheader schemas are listed on the following pages at MSDN: urn:schemas:httpmail: Namespace and urn:schemas:mailheader: Namespace.
To pick up a value from a different Outlook field, change the field name in
strFilter = oMail.SenderEmailAddress and change the search string used in strDASLFilter
This long filter covers the common search fields.
strDASLFilter = """urn:schemas:httpmail:fromname"" LIKE '%" & strFilter & "%' " + _ "OR ""urn:schemas:httpmail:textdescription"" LIKE '%" & strFilter & "%' " + _ "OR ""urn:schemas:httpmail:displaycc"" LIKE '%" & strFilter & "%' " + _ "OR ""urn:schemas:httpmail:displayto"" LIKE '%" & strFilter & "%' " + _ "OR ""urn:schemas:httpmail:subject"" LIKE '%" & strFilter & "%' " + _ "OR ""urn:schemas:httpmail:thread-topic"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/received_by_name"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8586001f"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/85a4001f"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/id/{00062041-0000-0000-C000-000000000046}/8904001f"" LIKE '%" & strFilter & "%' " + "OR ""http://schemas.microsoft.com/mapi/proptag/0x0e03001f"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/proptag/0x0e04001f"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/proptag/0x0042001f"" LIKE '%" & strFilter & "%' " + "OR ""http://schemas.microsoft.com/mapi/proptag/0x0044001f"" LIKE '%" & strFilter & "%' " + _ "OR ""http://schemas.microsoft.com/mapi/proptag/0x0065001f"" LIKE '%" & strFilter & "%' "
More Information
Search Object (Outlook) (MSDN)
(Less Than) Portable Search Folders (MSDN)
Is there any way that we can create a search folder based upon the email subject as a text.
this is use case: I click on a button on the outlook, a popup will appear, i put email subject sugh as "Sales Reports - 2023", then click on OK. then the VBS should pick this key word and create a search folder and collect all emails from the inbox?
Hi, Diane,
exactly as you put it.However, the macro stops at Set objSearch = Application.AdvancedSearch(Scope:=strScope, Filter:=strDASLFilter, SearchSubFolders:=True, Tag:="SearchFolder")
with error message -2147024809 (80070057): the operation cannot be completed as one parameter or more are improper.
I am using Windows 10, MS Outlook 10.
What’s wrong with this macro and what can I do to fix the error.
Outlook related mails - how to set custom search scope using VBA ?
Like; 'olSearchScopeCurrentFolder' searches Current folder & 'olSearchScopeSubfolders' searchs current folder and its sub folders. Id need to search Inbox, its subfolders & an another folder outside inbox tree. How to manage this ? kindly advice.
Thanks, Diane, for your excellent macros. There is one problem, that I cannot solve at myself and look forward to your help. I do appologize that for a lack of time I have not read all other comments to this thread.
Your procedure reads at the end:
In fact, the result is that the new folder with a specified name is created as a subfolder in "Search folder". However, if I want to write a code to do certain operations (such as sort mails in this subfolder by category the system does not see the parent search folder at all and I cannot do anything with mails in this new subfolder. Will you please guide me how to solve the problem.Best regards
Marek
you need to use getsearchfolders if you want to use code on search folders,
https://docs.microsoft.com/en-us/office/vba/api/outlook.store.getsearchfolders
Thanks a lot. Your advice (as it always does) has helped to solve my problem. Thanks a lot.
Great!
Looking forward for the hard coded example. It will work out perfectly because the target account is known and not supposed to change
Thanks!
This code will create a search folder in the selected data file and add it to favorites.
How to Create an Outlook Search Folder using VBA (slipstick.com)
Hello Diane,
first of all I wanted thank you for sharing your knowledge. Please allow me to ask you a question
I have multiple accounts in my Outlook and I have tried the SearchFolderForCategories sub.
The search folder created by objSearch.Save (oMail.Categories) it is always created under the same account. Do you know if it is possible to change this and specify under which account I want it to be created ?
Many thanks
Best,
As written, it is for the default account only. It is possible to get the current store and create it in that - I've been meaning to do that but haven't had tome yet.
Actually, in checking my mailbox, I do have one that is hard coded with the mailbox name. I'll add it to the page.
ETA: decided to make it work with whatever data file is selected
What if I want to retrieve the latest/ the newest email from/ to specific email address, what could be the filter?
You can't limit it to the newest or last - you can filter by date - received today, this week etc. But it will show all messages (or none) that arrived with that period that meet the other conditions.
Hi, I was wondering if there's a way to make a search folder for searching message class that contains "EMS"? also when I try the categories one im getting array index out of bounds