Create Outlook email routing rule based on ticket ID using VBA - vba

I tried to create email routing rule with below scenario.
Incoming email will be located at Inbox/Active folder. Subject of the email will contain the ticket ID and content
Once new email coming to Active subfolder, Outlook will get the email subject and create the subfolder with format "ticket ID - content" eg: "123123 - issue with outlook"
Then a rule will be created to route this incoming email with ticket ID to the subfolder that I just created
Below is my code but it did not work. Only subfolder is created as expected. Please help me to review if any idea. Thanks
Option Explicit
Private WithEvents inboxItems As Outlook.Items
Private Sub Application_Startup()
Dim olapp As Outlook.Application
Dim olnamespace As Outlook.NameSpace
Set olapp = Outlook.Application
Set olnamespace = olapp.GetNamespace("MAPI")
Set inboxItems = olnamespace.GetDefaultFolder(olFolderInbox).Folders("Filter").Items
End Sub
Private Sub inboxItems_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim olapp As Outlook.Application
Dim olnamespace As Outlook.NameSpace
Dim olActivefolder As Folder
Dim ticketnumber As String
Dim rightsubject As String
Dim leftsubject As String
Dim extsubject As String
Dim colRules As Outlook.Rules
Dim oRule As Outlook.Rule
Dim colRuleActions As Outlook.RuleActions
Dim oMoveRuleAction As Outlook.MoveOrCopyRuleAction
Dim oFromCondition As Outlook.ToOrFromRuleCondition
Dim oExceptSubject As Outlook.TextRuleCondition
Dim oInbox As Outlook.Folder
Dim oMoveTarget As Outlook.Folder
Set olapp = Outlook.Application
Set olnamespace = olapp.GetNamespace("MAPI")
Set olActivefolder = olnamespace.GetDefaultFolder(olFolderInbox).Folders("Active")
If TypeName(Item) = "MailItem" Then
Debug.Print "triggered"
ticketnumber = Item.Subject
rightsubject = Right(ticketnumber, 16)
leftsubject = Left(ticketnumber, 60)
olActivefolder.Folders.Add (rightsubject & " - " & leftsubject)
End If
Set oInbox = Application.Session.GetDefaultFolder(olFolderInbox).Folders("Active")
Set oMoveTarget = oInbox.Folders(rightsubject & " - " & leftsubject)
Set colRules = Application.Session.DefaultStore.GetRules()
Set oRule = colRules.Create(rightsubject, olRuleReceive)
Set oFromCondition = oRule.Conditions.Subject
With oFromCondition
.Enabled = True
.Text = rightsubject
End With
Set oMoveRuleAction = oRule.Actions.MoveToFolder
With oMoveRuleAction
.Enabled = True
.Folder = oMoveTarget
End With
colRules.Save
ExitNewItem:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ExitNewItem
End Sub

The subject condition should look like this:
'Dim oFromCondition As Outlook.ToOrFromRuleCondition
'Set oFromCondition = oRule.Conditions.subject
'With oFromCondition
' .Enabled = True
' .Text = rightSubject
'End With
Dim oSubjectCondition As TextRuleCondition
Set oSubjectCondition = oRule.Conditions.subject
With oSubjectCondition
.Enabled = True
.Text = Array(rightSubject)
End With

There is likely no need for rules.
Private Sub inboxItems_ItemAdd_Test()
inboxItems_ItemAdd ActiveInspector.CurrentItem
End Sub
Private Sub inboxItems_ItemAdd(ByVal Item As Object)
' Folder created for first mail
' No folder created for subsequent mail
Dim oInbox As folder
Dim oActivefolder As folder
Dim oMoveTarget As folder
Dim oFolder As folder
Dim ticketNumber As String
Set oInbox = Session.GetDefaultFolder(olFolderInbox)
Set oActivefolder = oInbox.Folders("Active")
If TypeName(Item) = "MailItem" Then
Debug.Print "triggered"
' For testing
ticketNumber = "123123"
For Each oFolder In oActivefolder.Folders
If oFolder.Name = ticketNumber Then
Set oMoveTarget = oActivefolder.Folders(ticketNumber)
Debug.Print " Folder exists: " & oMoveTarget.Name
Exit For
End If
Next
If oMoveTarget Is Nothing Then
Set oMoveTarget = oActivefolder.Folders.Add(ticketNumber)
Debug.Print " Folder added: " & oMoveTarget.Name
End If
Item.Move oMoveTarget
End If
Debug.Print "Done."
End Sub

Related

Set mails read if they were read in another folder

I'm trying to make an outlook macro, which will 'update' the mails. I have an Inbox folder and an another one. (2 mail accunts)
There is a rule, which is copying the mail from another folder to my inbox.
My goal is to set the mail as read in another folder, if it was read in the Inbox folder.
Sub precitane()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim mydeffolder As Outlook.Folder
Dim items As Object
Dim defitems As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myDestFolder = myNameSpace.Folders("") 'mymail
Set mydeffolder = myNameSpace.GetDefaultFolder(olFolderInbox)
For Each items In myDestFolder.items
For Each defitems In mydeffolder.items
If TypeOf items Is Outlook.MailItem & TypeOf defitems Is Outlook.MailItem Then
Dim oMail As Outlook.MailItem: Set oMail = items
Dim defMail As Outlook.MailItem: Set defMail = defitems
If oMail.SenderEmailAddress = "" & defMail.SenderEmailAddress = "" & defMail.Body = oMail.Body & defMail.UnRead = False Then
oMail.UnRead = True
oMail.Save
End If
End If
Next
Next
On Error GoTo 0
End Sub
"" contains my mail...
It looks like you tried with code from other than VBA.
I broke the If statement into separate parts as it is easier to follow and to debug.
Option Explicit
Sub precitane()
Dim myDestFolder As Folder
Dim mydeffolder As Folder
Dim item As Object
Dim defItem As Object
Set myDestFolder = Session.Folders("mailAddress2").Folders("Inbox").Folders("Test")
Set mydeffolder = Session.GetDefaultFolder(olFolderInbox).Folders("Test3")
For Each item In myDestFolder.items
If TypeOf item Is MailItem Then
For Each defItem In mydeffolder.items
If TypeOf defItem Is MailItem Then
If item.senderEmailAddress = defItem.senderEmailAddress Then
If item.Body = defItem.Body Then
If item.UnRead = False Then
defItem.UnRead = False
'If necessary
'item.Save
Exit For
End If
End If
End If
End If
Set defItem = Nothing
Next
End If
Set item = Nothing
Next
Debug.Print "Done."
End Sub

Only run if email has attachment

I want the below code to run when a specific subject appears in an email.
Also to only run if that email has an attachment.
Outlook ignores the attachment part of the rule, and tries to run the code even if the attachment is not there (it seems to only care about the subject).
How do I incorporate a check for attachment in the code?
Public Sub SaveAttachmentsThenOpen(MItem As Outlook.MailItem)
Dim oMail As Variant
Dim oReply As Outlook.MailItem
Dim oItems As Outlook.Items
Dim Msg As Outlook.MailItem
Dim oAttachment As Outlook.Attachment
Dim StrBody As String
Dim oRep As MailItem
Dim sSaveFolder As String
Dim Att As String
Dim Attname As String
Dim sht As Object
Dim Rng As Range
Dim s As String
Dim myAttachments As Outlook.Attachments
Dim XLApp As Object
Dim XlWK As Object
Dim strPaste As Variant
Set oApp = New Outlook.Application
Set oNs = oApp.GetNamespace("MAPI")
Set XLApp = CreateObject("Excel.Application")
With XLApp
.Visible = True
.ScreenUpdating = True
.Workbooks.Open ("C:\Directory\data.xlsx")
.Workbooks.Open ("C:\Directory\WB.xlsb")
End With
Dim strText As String
strText = ".xls"
sSaveFolder = "C:\Directory\TPS_Reports\"
For Each oAttachment In MItem.Attachments
If InStr(1, oAttachment.FileName, strText) > 0 Then
oAttachment.SaveAsFile sSaveFolder & oAttachment.FileName
Attname = oAttachment.FileName
Att = sSaveFolder & oAttachment.FileName
Exit For
End If
Next oAttachment
Set oAttachment = Nothing
XLApp.Workbooks.Open (Att)
XLApp.Visible = True
XLApp.Run ("WB.XLSB!MacroName")
Set sht = XLApp.Workbooks(Attname).ActiveSheet
Set Rng = sht.UsedRange
s = "<table border=1 bordercolor=black cellspacing=0>"
For rw = Rng.Row To Rng.Rows.Count
s = s & "<tr>"
For col = Rng.Column To Rng.Columns.Count
s = s & "<td>" & sht.Cells(rw, col) & "</td>"
Next
s = s & "</tr>"
Next
s = s & "</table>"
Set oRep = MItem.ReplyAll
With oRep
StrBody = "Hello"
.HTMLBody = s
.Send
End With
With XLApp
.DisplayAlerts = False
End With
XLApp.Workbooks(Attname).Save
XLApp.Quit
With XLApp
.DisplayAlerts = True
End With
End Sub
Try waiting for the mail to be in the inbox before checking for the attachment.
Code for the ThisOutlookSession module
Restart Outlook or run Application_Startup manually.
Private WithEvents myItems As Items
Private Sub Application_Startup()
Dim myInbox As folder
Set myInbox = Session.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
End Sub
Private Sub myItems_ItemAdd(ByVal Item As Object)
If TypeOf Item Is mailItem Then
If Item.Attachments.Count > 0 Then
SaveAttachmentsThenOpen Item
End If
End If
End Sub
Private Sub test()
myItems_ItemAdd ActiveInspector.currentItem
End Sub

How to forward, a mailItem copied from shared mailbox to local email folder, from local email?

I copy an email from a shared mailbox to a local folder in my Outlook.
I am trying to forward the email from my local email account.
When I do this, it is sent from the shared mailbox account.
I set the account on the email as the confirmed correct account.
mailItem.Move myDestFolder
Set mailItem2 = mailItem.Forward
mailItem2.SendUsingAccount = oAccount (where oAccount is OutApp.Session.Accounts.Item (1))
mailItem2.Send
set mailItem2.SendUsingAccount = oAccount results in error
Property is Read-Only
Wondering if I don't have permissions to set this?
Option Explicit
Private rcvMail As Outlook.MailItem
Private fwMail As Outlook.MailItem
Private Const STR_MOVED_FOLDER As String = "Moved Emails"
Sub MoveAndForward()
Dim myNamespace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim rcvFolder As Outlook.Folder
Dim oAccount As Outlook.Account
Dim myItems As Outlook.Items
Dim myItem As Object
Dim OutApp1 As Object
Dim mailBoxFolderName As String
Dim iEmailAccount As Integer
Dim iRecipientCount As Integer
Dim i As Integer
Set OutApp1 = CreateObject("Outlook.Application")
Set oAccount = OutApp1.Session.Accounts.Item(1)
Set myNamespace = Application.GetNamespace("MAPI")
Set myInbox = myNamespace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
CheckOrCreateFolder
Set myDestFolder = myInbox.Folders(STR_MOVED_FOLDER)
Set rcvMail = ReturnCurrentItem()
If rcvMail.Class <> olMail Then
MsgBox "This cannot be saved to file." & vbCrLf & _
"Only Mail Items are supported.", vbExclamation, "Error"
Exit Sub
End If
Set rcvFolder = rcvMail.Parent
mailBoxFolderName = rcvFolder.Name
rcvMail.Move myDestFolder
Set fwMail = rcvMail.Forward
Set fwMail.SendUsingAccount = oAccount
iRecipientCount = fwMail.Recipients.Count
If iRecipientCount > 0 Then
For i = iRecipientCount To 1 Step -1
fwMail.Recipients.Remove (i)
Next i
End If
fwMail.Recipients.Add "*****#***.com"
fwMail.Recipients.ResolveAll
fwMail.Body = myNamespace.CurrentUser & " Took this email from the Mailbox" & _
vbCrLf & rcvMail.Body
fwMail.Send
rcvMail.Close (olDiscard)
Set rcvMail = Nothing
Set fwMail = Nothing
Set myNamespace = Nothing
Set myInbox = Nothing
Set myItems = Nothing
Set myDestFolder = Nothing
End
End Sub

Issue with Class Module Outlook VBA

I am new to VBA and am trying to insert a class module to save an email that arrives to a sub-folder in the inbox called "My Folder" to a location on a sharedrive. I have the below code and have tried sending emails to test but it is not working and cannot figure out why. Any help would be greatly appreciated!
Private WithEvents InboxItems As Outlook.Items
Sub Application_Startup()
Dim xNameSpace As Outlook.NameSpace
Set xNameSpace = Outlook.Application.Session
Set InboxItems = xNameSpace.GetDefaultFolder(olFolderInbox)
Set InboxItems = olFolder.Folders("My Folder")
End Sub
Private Sub InboxItems_ItemAdd(ByVal objItem As Object)
Dim FSO
Dim xMailItem As Outlook.MailItem
Dim xFilePath As String
Dim xRegEx
Dim xFileName As String
On Error Resume Next
xFilePath = CreateObject("WScript.Shell").SpecialFolders(16)
xFilePath = xFilePath & "File Path on Share Drive will be entered here"
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(xFilePath) = False Then
FSO.CreateFolder (xFilePath)
End If
Set xRegEx = CreateObject("vbscript.regexp")
xRegEx.Global = True
xRegEx.IgnoreCase = False
xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"
If objItem.Class = olMail Then
Set xMailItem = objItem
xFileName = xRegEx.Replace(xMailItem.Subject, "")
xMailItem.SaveAs xFilePath & "\" & xFileName & ".msg", olMSG
End If
Exit Sub
End Sub
There were a few issues with the code that I saw. I have this working, make sure you add this to the ThisOutlookSession object in the VBA IDE.
Private WithEvents InboxItems As Outlook.Items
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Set InboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal Item As Object)
Dim FolderPath As String: FolderPath = "YOUR PATH HERE"
Dim FileName As String
Static FSO As Object
If FSO Is Nothing Then Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FolderExists(FolderPath) = False Then FSO.CreateFolder FolderPath
With CreateObject("vbscript.regexp")
.Global = True
.IgnoreCase = False
.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"
If Item.Class = olMail Then
FileName = .Replace(Item.Subject, vbNullString)
Item.SaveAs FolderPath & FileName & ".msg", olMSG
End If
End With
End Sub

Folder path to enterprise vault using VBA for email migration

I have a long list of folders and to many rules for outlook to handle using the standard rules manager. I wrote code that would classify and move items to folders but recently I was migrated to an Enterprise Vault. I am trying to find the folder path to update my code. I tried something like
Outlook.Application.GetNamespace("MAPI").Folders("Vault - DOE, JOHN").Folders("My Migrated PSTs").Folders("PR2018")
but honestly I have no idea what the correct path should be. Everything I find online deals with pulling selected items out of the vault and not moving items into it. Below is an excerpt of the existing code. This is on Office 365/Outlook 2016.
Sub Sort_Test(Item)
Dim Msg As Object
Dim Appt As Object
Dim Meet As Object
Dim olApp As Object
Dim objNS As Object
Dim targetFolder As Object
On Error GoTo ErrorHandler
Set Msg = Item
Set PST = Outlook.Application.GetNamespace("MAPI").Folders("PR2018")
checksub = Msg.Subject
checksend = Msg.Sender
checksendname = Msg.SenderName
checksendemail = Msg.SenderEmailAddress
checkbod = Msg.Body
checkto = Msg.To
checkbcc = Msg.BCC
checkcc = Msg.CC
checkcreation = Msg.CreationTime
checksize = Msg.Size
'Classes Folder
If checksub Like "*Files*Lindsey*" Or checksub Like "*Course Login*" _
Or checksend Like "*Award*eBooks*" Then
Set targetFolder = PST.Folders("Education").Folders("Classes")
Msg.Move targetFolder
GoTo ProgramExit
End If
If targetFolder Is Nothing Then
GoTo ProgramExit
' Else
' Msg.Move targetFolder
End If
' Set olApp = Nothing
' Set objNS = Nothing
Set targetFolder = Nothing
Set checksub = Nothing
Set checksend = Nothing
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
Try this code:
Sub MoveToFolder()
Dim olApp As New Outlook.Application
Dim olNameSpace As Outlook.NameSpace
Dim olArcFolder As Outlook.MAPIFolder
Dim olCompFolder As Outlook.MAPIFolder
Dim mailboxNameString As String
Dim myInspectors As Outlook.MailItem
Dim myCopiedInspectors As Outlook.MailItem
Dim myItem As Outlook.MailItem
Dim M As Integer
Dim iCount As Integer
Set olNameSpace = olApp.GetNamespace("MAPI")
Set olArcFolder = olNameSpace.Folders("Emails Stored on Computer").Folders("Archived")
Set olCompFolder = olNameSpace.Folders("Emails Stored on Computer").Folders("Computer")
For M = 1 To olArcFolder.items.Count
Set myItem = olArcFolder.items(M)
myItem.Display
Set myInspectors = Outlook.Application.ActiveInspector.CurrentItem
Set myCopiedInspectors = myInspectors.copy
myCopiedInspectors.Move olCompFolder
myInspectors.Close olDiscard
Next M
Here is a link for you reference:
Do for all open emails and move to a folder