0

I am trying to put a category on all the e-mails that have the same first 15 characters of the subject.

I have a script (which I borrowed here Macro in Outlook to delete duplicate emails-) that compares subject and body of e-mails, finds duplicates and moves them to the Deleted Items.

I would like to modify it to compare only the first 15 characters of subject and categorizes e-mails instead of deleting them.

Option Explicit

'Set a reference to the Microsoft Scripting Runtime from Tools, References.

Sub CategorizeDuplicateEmailsInSelectedFolder()

Dim i As Long
Dim n As Long
Dim Message As String
Dim Items As Object
Dim AppOL As Object
Dim NS As Object
Dim Folder As Object

Set Items = CreateObject("Scripting.Dictionary")

'Initialize and instance of Outlook
Set AppOL = CreateObject("Outlook.Application")

'Get the MAPI Name Space
Set NS = AppOL.GetNamespace("MAPI")

'Allow the user to select a folder in Outlook
Set Folder = NS.PickFolder

'Get the count of the number of emails in the folder
n = Folder.Items.Count

'Check each email starting from the last and working backwards to 1
'Loop backwards to ensure that the deleting of the emails does not interfere with subsequent items in the loop
For i = n To 1 Step -1

    On Error Resume Next
    'Load the matching criteria to a variable
    'This is setup to use the Subject
    Message = Folder.Items(i).Subject <- this part needs to be modifed

        'Check a dictionary variable for a match
        If Items.Exists(Message) = True Then
        'If the item has previously been added then categorize this duplicate
        Folder.Items(i).Categories = "Blue category" <- this part needs to be modifed
    Else
        'In the item has not been added then add it now so subsequent matches will be categorized
        Items.Add Message, True
End If

Next i

ExitSub:

'Release the object variables from memory
Set Folder = Nothing
Set NS = Nothing
Set AppOL = Nothing

End Sub
Laurel
  • 5,965
  • 14
  • 31
  • 57
jerkdavi
  • 47
  • 2
  • 9
  • Does this answer your question? [If email subject line starts with certain values then do something](https://stackoverflow.com/questions/30613626/if-email-subject-line-starts-with-certain-values-then-do-something) – niton Dec 20 '21 at 15:51

2 Answers2

1

This turned out to be trickier than it first appeared.

Option Explicit

'Set a reference to the Microsoft Scripting Runtime from Tools, References.

Sub CategorizeDuplicateEmailsInSelectedFolder()

Dim i As Long
Dim n As Long

Dim startSubject As String
Dim dictItems As Object

Dim pFolder As Object
Dim pFolderItems As Items
Dim msgObj As mailItem

Set dictItems = CreateObject("Scripting.Dictionary")

'Allow the user to select a folder in Outlook
Set pFolder = Session.PickFolder
If pFolder Is Nothing Then Exit Sub

Set pFolderItems = pFolder.Items

'Get the count of the number of emails in the folder
n = pFolderItems.Count

pFolderItems.Sort "[ReceivedTime]", True

'Check each email starting from the oldest
For i = n To 1 Step -1

    If TypeName(pFolderItems(i)) = "MailItem" Then
    
        Set msgObj = pFolderItems(i)
        
        'Load the matching criteria to a variable
        'This is setup to use the Subject
        'Message = Folder.Items(i).subject ' <- this part needs to be modifed
        startSubject = Left(msgObj.subject, 15)
        Debug.Print startSubject
        
        'Check a dictionary variable for a match
        If dictItems.Exists(startSubject) = True Then
            'If the item has previously been added then categorize this duplicate
            
            'pFolderItems(i).categories = "Blue category" ' <- This did not save
            
            msgObj.categories = "Blue category" ' <- This could be saved
            msgObj.Save
            
        Else
            'In the item has not been added then add it now so subsequent matches will be categorized
            dictItems.Add startSubject, True
        End If
    End If
Next i

End Sub

https://excelmacromastery.com/vba-error-handling/#On_Error_Resume_Next
"There are specific occasions when this is useful. Most of the time you should avoid using it."

niton
  • 8,771
  • 21
  • 32
  • 52
  • Sorry for the late reply. This answers my question. Thank you so much for your help! If you would allow me to be a stickler for a sec, I would have 2 more questions. It doesn't categorize all of the e-mails with the same first 15 chars of the subject. 1 e-mail remains uncategorized, which is expected since it uses that first e-mail as a reference point to compare other e-mails with. Could it be done that it categorizes that e-mail too? Ideally, 1 e-mail should remain uncategorized the most recent received one, but categorizing all e-mails with the same first 15 chars is second best. – jerkdavi Dec 22 '21 at 16:13
  • Second question would be, if the categorizing part could be done without overriding the category already set to the e-mail, if one already exists? Current function tramples already set categories and imposes category 'blue'. I would like if it could only add category 'blue'. As I said above, I am being a stickler now. I am more than satisfied with your answer, and thank you once more, but if these two things could be added, that would be pure perfection. Cheers! – jerkdavi Dec 22 '21 at 16:19
  • To check each email starting from the most recent `For i = 1 To n`. – niton Dec 23 '21 at 00:04
  • `InStr` to identify already existing category. Add with a comma delimiter. [Add category without removing existing categories](https://stackoverflow.com/questions/32700410/add-category-without-removing-existing-categories) / [Mark an item with a particular category](https://stackoverflow.com/questions/7439187/mark-an-item-with-a-particular-category). – niton Dec 23 '21 at 00:10
  • Thank you so much! Changed: `For i = n To 1 Step -1` to `For i = 1 To n Step +1` and `msgObj.categories = "Blue category"` to `msgObj.categories = msgObj.categories & "," & "Blue category"` and now it works perfectly! – jerkdavi Dec 23 '21 at 07:26
  • If you find "Blue category" appears multiple times `If InStr(msgObj.categories, "Blue category") = 0 Then` to verify it is not there before adding. – niton Dec 23 '21 at 16:47
0

I am trying to make a macro in Outlook that will put a category on all the e-mails that have the same first 15 characters of the subject.

To find all items with the same Subject string (with first 15 characters) you can use the Find/FindNext or Restrict methods of the Items class. Read more about these methods in the following articles:

Also you may consider using the Folder.GetTable method which obtains a Table object that contains items filtered by filter. GetTable returns a Table with the default column set for the folder type of the parent Folder. To modify the default column set, use the Add, Remove, or RemoveAll methods of the Columns collection object.

Sub RestrictTableOfInbox() 
    Dim oT As Outlook.Table 
    Dim strFilter As String 
    Dim oRow As Outlook.Row 
     
    'Construct filter for Subject containing 'your_15_characters' 
    Const PropTag  As String = "https://schemas.microsoft.com/mapi/proptag/" 
    strFilter = "@SQL=" & Chr(34) & PropTag  _ 
        & "0x0037001E" & Chr(34) & " ci_phrasematch 'your_15_characters'" 
     
    'Do search and obtain Table on Inbox 
    Set oT = Application.Session.GetDefaultFolder(olFolderInbox).GetTable(strFilter) 
     
    'Print Subject of each returned item 
    Do Until oT.EndOfTable 
        Set oRow = oT.GetNextRow 
        Debug.Print oRow("Subject") 
    Loop 
End Sub

Also you may take a look at the Application.AdvancedSearch method which performs a search based on a specified DAV Searching and Locating (DASL) search string. The key benefits of using the AdvancedSearch method in Outlook are:

  • The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
  • Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
  • Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
  • You can stop the search process at any moment using the Stop method of the Search class.

Read more about that method in the Advanced search in Outlook programmatically: C#, VB.NET article.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Sorry for the late reply. This answer is definitely too sophisticated for my current level of understanding VBA. I need to spend some time studying the material you provided. Thank you for the reply! – jerkdavi Dec 22 '21 at 15:59
  • You may find the [Getting started with VBA in Office](https://learn.microsoft.com/en-us/office/vba/library-reference/concepts/getting-started-with-vba-in-office) article helpful. – Eugene Astafiev Dec 22 '21 at 16:54