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