Trigger ItemSend for certain outlook macros only - vba

How would I modify the following code to trigger the event myMailItem_ItemSend only when the email is sent by myMacro1, but not in other cases (such as myMacro2)?
The event should be triggered especially for those macros using the myMailItem object.
Public WithEvents myMailItem As Outlook.MailItem
Public Sub Initialize_handler()
Set myMailItem = Outlook.MailItem
End Sub
Private Sub myMailItem_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim prompt As String
prompt = "Are you sure you want to send " & Item.Subject & "?"
If MsgBox(prompt, vbYesNo + vbQuestion, "Send confirmation") = vbNo Then
Cancel = True
End If
End Sub
'Should trigger the send confirmation msgbox
Private Sub myMacro1()
Dim objApp As Outlook.Application
Set objApp = Application
Set myMailItem = objApp.ActiveInspector.CurrentItem.ReplyAll
myMailItem.Display
End Sub
'Should NOT trigger the send confirmation msgbox
Private Sub myMacro2()
Dim objApp As Outlook.Application
Set objApp = Application
Dim oEmail As Outlook.mailItem
Set oEmail = objApp.ActiveInspector.CurrentItem.ReplyAll
oEmail.Display
End Sub
Your kind help would be appreciated.

I would go for this:
Define a global variable in your module, such as Dim TriggerMsgBox As Boolean. By default, the variable will be false.
Initialize it as True in the myMacro1(). Only in that case, it will become True. Else, it will be False.
Use it in the myMailItem_ItemSend event: if the variable is True (meaning we just passed by myMacro1()), then you need to prompt the MsgBox. Else, you will just pass by. Of course, don't forget to reset the variable to False after the MsgBox is hit, else you will keep on showing it even later.
In your code it would be:
Public WithEvents myMailItem As Outlook.MailItem
Dim TriggerMsgBox As Boolean '<-- NEW LINE OF CODE
Public Sub Initialize_handler()
Set myMailItem = Outlook.MailItem
End Sub
Private Sub myMailItem_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim prompt As String
If TriggerMsgBox Then '<-- NEW LINE OF CODE
TriggerMsgBox = False '<-- NEW LINE OF CODE
prompt = "Are you sure you want to send " & Item.Subject & "?"
If MsgBox(prompt, vbYesNo + vbQuestion, "Send confirmation") = vbNo Then
Cancel = True
End If
End If '<-- NEW LINE OF CODE
End Sub
'Should trigger the send confirmation msgbox
Private Sub myMacro1()
Dim objApp As Outlook.Application
Set objApp = Application
Set myMailItem = objApp.ActiveInspector.CurrentItem.ReplyAll
TriggerMsgBox = True '<-- NEW LINE OF CODE
myMailItem.Display
End Sub
'Should NOT trigger the send confirmation msgbox
Private Sub myMacro2()
Dim objApp As Outlook.Application
Set objApp = Application
Dim oEmail As Outlook.mailItem
Set oEmail = objApp.ActiveInspector.CurrentItem.ReplyAll
oEmail.Display
End Sub

Related

VBA OUTLOOK - PropertyChange Gets Activated By MsgBox Multiple Times

I'm writing a multi-purpose code in ThisOutlookSession, one part of the code has the job to get activated by PropertyChange in CurrentItem and if Subject is equal to a specific value, it first opens a MsgBox, on VBYes it Copies a value that is stored inside a .txt file and opens a mail with an .HTMLBody with that value.
It works fine if in the MsgBox input you answer VbYes, but if you answer VbNo then the PropertyChange is activated 3 times, in this case I have to answer 3 times VbNo.
I can actually see that the appearence of the MsgBox triggers the m_inspector_activate() which makes the code think that the Subject changed another time (this is how I think it works).
I will leave a shortened part of the code to let you see what I'am talking about.
Please text me if you do not understand something.
Option Explicit
'global variable used to disable the trigger of oItem_Forward(), oItem_Reply() and oItem_ReplyAll() while myItem_PropertyChange() is working
Public disableevents As Boolean
'private variables used to display mailitem on Reply, ReplyAll or Forward
Private WithEvents oExpl As Explorer
Private WithEvents oItem As MailItem
'private variables used ad inspectors in PropertyChange and ItemSend
Private WithEvents m_Inspectors As Outlook.Inspectors
Private WithEvents m_Inspector As Outlook.Inspector
Private WithEvents myItem As Outlook.MailItem
'declaration necessary to manage the forwards, replies and replyall events, recognizes the discard
Private bDiscardEvents As Boolean
'declaration of variable that manages the forwards, replies and replyall events
Dim exception As MailItem
'sub activated by opening outlook, it sets the inspectors
Private Sub Application_Startup()
Set oExpl = Application.ActiveExplorer
Set m_Inspectors = Application.Inspectors
bDiscardEvents = False
End Sub
'sub that on change of item selection, sets and stores the value of oItem variable to later open the forward, reply or replyall
Private Sub oExpl_SelectionChange()
' the on error avoids the error in case the item is not mailitem
On Error Resume Next
Set oItem = oExpl.selection.item(1)
End Sub
'sub activated by the event of pressing "reply"
Private Sub oItem_Reply(ByVal Response As Object, Cancel As Boolean)
' disableevents variable exits sub if its true, blocks the activation if myItem_PropertyChange() is working
On Error Resume Next
If disableevents = True Then Exit Sub
Cancel = True
bDiscardEvents = True
'displays the before selected email when the button "reply" was pressed
Set exception = oItem.Reply
exception.Display
End Sub
'sub activated by the event of pressing "forward"
Private Sub oItem_Forward(ByVal Response As Object, Cancel As Boolean)
' disableevents variable exits sub if its true, blocks the activation if myItem_PropertyChange() is working
On Error Resume Next
If disableevents = True Then Exit Sub
Cancel = True
bDiscardEvents = True
'displays the before selected email when the button "forward" was pressed
Set exception = oItem.Forward
exception.Display
End Sub
'sub activated by the event of pressing "replyall"
Private Sub oItem_ReplyAll(ByVal Response As Object, Cancel As Boolean)
' disableevents variable exits sub if its true, blocks the activation if myItem_PropertyChange() is working
On Error Resume Next
If disableevents = True Then Exit Sub
Cancel = True
bDiscardEvents = True
'displays the before selected email when the button "replyall" was pressed
Set exception = oItem.ReplyAll
exception.Display
End Sub
' on NewInspector it sets the inspectors variables
Private Sub m_Inspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
If TypeOf Inspector.CurrentItem Is Outlook.MailItem Then
'Handle emails only:
Set oExpl = Application.ActiveExplorer
Set m_Inspector = Inspector
bDiscardEvents = False
End If
End Sub
'on m_Inspector activation the subs sets myItem variable
Private Sub m_Inspector_Activate()
If TypeOf m_Inspector.CurrentItem Is MailItem Then
Set myItem = m_Inspector.CurrentItem
End If
End Sub
'on myItem Property Change sub starts, this subs checks for subject, if subject is equal to a specific value then opens a mail using a .txt file(with html code inside) to use it as a template
Private Sub myItem_PropertyChange(ByVal Name As String)
'variables necessary to pull data from .txt file and then put it inside .HTMLBody
Dim FilePath As String
Dim TextFile As Integer
Dim FileContent As String
'inspector, explorer and mailitem used to check for subject, open selected mail and then open the "template"
Dim exp As Explorer
Dim ite As Inspector
Dim selection As selection
Dim currentmail As MailItem
Dim selectedmail As MailItem
'active part of the code where we set the various explorer, inspector and mailitems
Set exp = Outlook.ActiveExplorer
Set ite = Outlook.ActiveInspector
On Error Resume Next
Set currentmail = ite.CurrentItem
Set selection = exp.selection
On Error Resume Next
Set selectedmail = selection.item(1)
'variable that lowercases the current item subject to make it non-case sensitive
Dim lsubject As String
lsubject = LCase(myItem.Subject)
'variable that gets user's username
Dim varia As String
varia = Environ("username")
'if cycle that checks first for ConversationIndex (to control if this is a NewMail) and if lsubject (lowercase subject) is equal to a value then opens the "template"
If Len(currentmail.ConversationIndex) = 0 Then
If lsubject = "reso" Then
If MsgBox("Vuoi aprire il template ""Reso merce non conforme""?", vbYesNo) = vbYes Then
disableevents = True
FilePath = "INSERT YOUR PATH"
TextFile = FreeFile
Open FilePath For Input As TextFile
FileContent = Input(LOF(TextFile), TextFile)
Close TextFile
currentmail.Close False
Set it = Application.CreateItem(olMailItem)
With it
.To = currentmail.To
.CC = currentmail.CC
.HTMLBody = FileContent
.Display
End With
disableevents = False
Else
GoTo endvb
End if
End If
ElseIf Len(currentmail.ConversationIndex) <> 0 Then
If lsubject = "reso" Then
If MsgBox("Vuoi aprire il template ""Reso merce non conforme""?", vbYesNo) = vbYes Then
disableevents = True
FilePath = "INSERT YOUR PATH"
TextFile = FreeFile
Open FilePath For Input As TextFile
FileContent = Input(LOF(TextFile), TextFile)
Close TextFile
currentmail.Close False
selectedmail.Display
Set it = selectedmail.ReplyAll
With it
.To = selectedmail.To
.CC = selectedmail.CC
.HTMLBody = FileContent & it.HTMLBody
.Display
End With
disableevents = False
Else
GoTo endvb
End If
End If
End If
endvb:
End Sub
Function GetCurrentItem() As Object
'function that recognizes if email is open (active inspector) or if email is only selected and previewed (explorer)
Dim objApp As Outlook.Application
Set objApp = Application
On Error Resume Next
Select Case TypeName(objApp.ActiveWindow)
Case "Explorer"
Set GetCurrentItem = objApp.ActiveExplorer.selection.item(1)
Case "Inspector"
Set GetCurrentItem = objApp.ActiveInspector.CurrentItem
End Select
Set objApp = Nothing
End Function
Private Sub Application_ItemSend(ByVal item As Object, Cancel As Boolean)
'declaration of inspector and mail item
Dim ispettore As Outlook.Inspector
Dim mails As MailItem
'APIs to recognize the presence of attachments
Const PR_ATTACH_CONTENT_ID As String = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"
Const PR_ATTACHMENT_HIDDEN As String = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"
'variables for the attachment
Dim itemcorr As Outlook.MailItem
Dim miallegati As Outlook.Attachments
' setting the activeinspector and using the function Getcurrenitem() to choose for inspector or explorer, I use the error to avoid the errors generated from appointment items
Set ispettore = Application.ActiveInspector
On Error Resume Next
Set mails = GetCurrentItem()
On Error Resume Next
'variables that make possible the non case sensitive search in the HTMLBody of the email, the UpperCase stores the HTMLBody and the LowerCase makes the first variable lowercase
Dim UpperCase As String, LowerCase As String
On Error Resume Next
UpperCase = mails.HTMLBody
On Error Resume Next
LowerCase = LCase(UpperCase)
On Error Resume Next
Dim it As Variant
On Error Resume Next
'variables needed to check only the first email and not the previously sent ones
Dim testo As String
Dim range As String
Dim numero As String
Dim textcheck As String
Dim rangealt As String
Dim textcheckalt As String
Dim numeroalt As String
Dim textcheckeng As String
Dim numeroeng As String
Dim rangeeng As String
'variable that gets user's username
Dim varia As String
varia = Environ("username")
'variable to print "allegato" or "allegati" in the msgbox
Dim msgboxvar As String
testo = mails.HTMLBody
textcheck = "<div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'>" 'text to check when email is correctly compiled and has got the line that divide the messages
textcheckalt = "-----Messaggio originale-----" 'text to check if email is sent from phone or if not correctly compiled
textcheckeng = "-----Original Message-----" 'text to check if email is sent from phone or if not correctly compiled and is in english
numero = InStr(testo, textcheck)
numeroalt = InStr(testo, textcheckalt)
numeroeng = InStr(testo, textcheckeng)
range = Left(testo, numero)
rangealt = Left(testo, numeroalt)
rangeeng = Left(testo, numeroeng)
'variables to find the possible attachments
Dim aFound As Boolean
Dim a As Object
Set miallegati = mails.Attachments
aFound = False
'if cicle that check the presence of attachment and if yes populates the variable aFound with True value
If TypeOf item Is Outlook.MailItem Then
For Each a In item.Attachments
On Error Resume Next ' to avoid the error thrown when no items within attachments have this property
If a.PropertyAccessor.GetProperty(PR_ATTACHMENT_HIDDEN) = False Then
If Len(a.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_ID)) > 0 And InStr(Application.ActiveInspector.CurrentItem.HTMLBody, a.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_ID)) Then
Else
aFound = True
Exit For
End If
End If
On Error GoTo 0
Next a
'if cicle that checks the desired portion of text for the word "allegato" or "allegati"
If aFound = False And InStr(LCase(range), "allegato") > 0 Then
GoTo singular
ElseIf aFound = False And InStr(LCase(range), "allegati") > 0 Then
GoTo plural
ElseIf aFound = False And InStr(LCase(rangealt), "allegato") > 0 Then
GoTo singular
ElseIf aFound = False And InStr(LCase(rangeeng), "allegato") > 0 Then
GoTo singular
ElseIf aFound = False And InStr(LCase(rangealt), "allegati") > 0 Then
GoTo plural
ElseIf aFound = False And InStr(LCase(rangeeng), "allegati") > 0 Then
GoTo plural
ElseIf aFound = False And InStr(LCase(range), "allegato") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(range), "allegati") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(rangealt), "allegato") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(rangealt), "allegati") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(rangeeng), "allegato") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(rangeeng), "allegati") = 0 And range <> "" Then
GoTo fine
ElseIf aFound = False And InStr(LCase(mails.HTMLBody), "allegato") > 0 Then
GoTo singular
ElseIf aFound = False And InStr(LCase(mails.HTMLBody), "allegati") > 0 Then
GoTo plural
Else
GoTo fine
'lines that set the variable msgboxvar for plural or singluar word in msgbox
plural: msgboxvar = "allegati"
GoTo msg
singular: msgboxvar = "allegato"
GoTo msg
'this last if checks for the whole text
LastIf: If aFound = False And InStr(LowerCase, "allegato") > 0 Or InStr(LowerCase, "allegati") > 0 Then
msgboxvar = "allegato"
'msg that signals the absence of attachments and asks if mail has to be sent, if answer is no, a word application makes it possible to attach chosen files to the email
msg: If MsgBox("Nell'email hai scritto '" & msgboxvar & "' ma non ne รจ presente alcuno, vuoi inviarla lo stesso?", vbYesNo) = vbNo Then
' user clicked cancel
Cancel = True
End If
End If
End If
End If
fine: End Sub
I have left the other sub that check for the attachment just to let you see if there are any conflicts.
First, the MailItem.PropertyChange event is fired when an explicit built-in property (for example, Subject) of an instance of the parent object is changed. The name of the property that was changed is passed as a parameter. So, you may check the property changed and process only changes in the Subject line.
Second, in the event handlers like Reply, Forward and etc. you trigger the event by calling corresponding methods in the code:
Private Sub oItem_Reply(ByVal Response As Object, Cancel As Boolean)
'...
Set exception = oItem.Reply
End Sub
Instead, you need to use the object passed as a parameter:
ByVal Response As Object
Third, in the NewInspector event handler the following code is used to get the inspector window:
Private Sub m_Inspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
'...
Set m_Inspector = Inspector
End Sub
Be aware, a new inspector instance is passed as a parameter to the event handler.
You may find the Implement a wrapper for inspectors and track item-level events in each inspector article helpful.

Delete draft mail on close when not sent

I've got some draft mails with some buttons to copy and open them. Only a few values need to be filled in and then the mails will be sent. I want to keep the drafts. But if a mail is not sent, I would like to delete it because it is a copy. I'm working with the close event for a mail item, but I can't seem to find out how to delete it in that sub, tried many things. Anyone knows how to approach this?
Code I got so far in a module:
Dim itmevt As New CMailItemEvents
Public olMail As Variant
Public olApp As Outlook.Application
Public olNs As NameSpace
Public Fldr As MAPIFolder
Sub TeamcenterWEBAccount()
Dim i As Integer
Dim olMail As Outlook.MailItem
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderDrafts)
For Each olMail In Fldr.Items
If InStr(olMail.Subject, "New account") <> 0 Then
Set NewItem = olMail.Copy
olMail.Display
Set itmevt.itm = olMail
Exit Sub
End If
Next olMail
End Sub
Code in the CMailItemEvents class module:
Option Explicit
Public WithEvents itm As Outlook.MailItem
Private Sub itm_Close(Cancel As Boolean)
Dim blnSent As Boolean
On Error Resume Next
blnSent = itm.Sent
If blnSent = False Then
itm.DeleteAfterSubmit = True
Else
' do
End Sub
Please, try the next way:
Copy the next adapted code (instead of your code, or in a new standard module):
Option Explicit
Private itmevt As New CMailItemEvents
Public deleteFromDrafts As Boolean, boolContinue As Boolean
Sub TeamcenterWEBAccount()
Dim olMail As Outlook.MailItem, NewItem As Outlook.MailItem, boolDisplay As Boolean
Dim olApp As Outlook.Application, Fldr As MAPIFolder, olNs As NameSpace
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderDrafts)
For Each olMail In Fldr.Items
If InStr(olMail.Subject, "New account") > 0 Then
On Error Resume Next 'for the case of inline response
Set NewItem = olMail.Copy
If Err.Number = -2147467259 Then
Err.Clear: On Error GoTo 0
olMail.Display: boolDisplay = True
For i = 1 To 1000: DoEvents: Next i 'just wait for the window to be displayed...
Set NewItem = olMail.Copy
End If
On Error GoTo 0
deleteFromDrafts = False: boolContinue = False 'initialize the boolean variables to wait for them in the loop
If Not boolDisplay Then olMail.Display
Set itmevt.itm = olMail
'wait for close event to be triggered...
Do While deleteFromDrafts = False And boolContinue = False
DoEvents
Loop
If deleteFromDrafts Then
If Not olMail Is Nothing Then olMail.Delete 'let only the copy...
End If
Exit Sub
End If
Next olMail
End Sub
Copy the next adapted code to replace the existing one in the used class:
Option Explicit
Public WithEvents itm As Outlook.MailItem
Private Sub itm_Close(Cancel As Boolean)
Dim blnSent As Boolean
On Error GoTo Ending 'for the case of mail sending, when itm looses its reference...
If blnSent = False Then
itm.DeleteAfterSubmit = True
deleteFromDrafts = True
Else
boolContinue = True
End If
Exit Sub
Ending:
boolContinue = True
End Sub
Tested, but not intensively...
Please, send some feedback after testing it in your specific environment.
First of all, iterating over all items in the folder is not really a good idea:
For Each olMail In Fldr.Items
If InStr(olMail.Subject, "New account") <> 0 Then
Instead, let the store provider do the job for you. The Find/FindNext or Restrict methods of the Items class allows getting items that correspond to your conditions, so you could iterate over items needed. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
You may try handling the Close event of the Inspector class which is fired when the inspector associated with a Microsoft Outlook item is being closed.
But I think none of them can be helpful. You need to re-design the whole solution by tracking for new items in the folder. And if new items have a custom property which indicates whether to remove the item or not you can do the additional actions. In the item-level event it is impossible to delete the source item.
My changes in module:
Private itmevt As New CMailItemEvents
Public deleteFromDrafts As Boolean, boolContinue As Boolean, boolDisplay As Boolean
Private olMail As Outlook.MailItem, NewItem As Outlook.MailItem
Private olApp As Outlook.Application, olNs As NameSpace, Fldr As MAPIFolder
Sub TeamcenterWEBAccount()
AccountOrInstallation ("Nieuw TC11 VDL ETG Teamcenter WEB account")
End Sub
Sub AccountOrInstallation(ByVal SearchStr As String)
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderDrafts)
For Each olMail In Fldr.Items
If InStr(olMail.Subject, SearchStr) > 0 Then
On Error Resume Next 'for the case of inline response
Set NewItem = olMail.Copy
If Err.Number = -2147467259 Then
Err.Clear: On Error GoTo 0
olMail.Display: boolDisplay = True
For i = 1 To 1000: DoEvents: Next i 'just wait for the window to be displayed...
Set NewItem = olMail.Copy
End If
On Error GoTo 0
deleteFromDrafts = False: boolContinue = False 'initialize the boolean variables to wait for them in the loop
If Not boolDisplay Then olMail.Display
Set itmevt.itm = olMail
'wait for close event to be triggered...
Do While deleteFromDrafts = False And boolContinue = False
DoEvents
Loop
If deleteFromDrafts Then
If Not olMail Is Nothing Then olMail.Delete 'let only the copy...
End If
Exit Sub
End If
Next olMail
End Sub

How to auto forward an email from a specific sender and with a specific subject?

I am trying to auto forward an email from a specific sender and with a specific subject to a list of new recipients.
When I create a Run a Script Rule, my script is not shown.
Add my script via VBA Editor
Rules > Manage Rules & Alerts > Run a script
Select Run a script action -> Can not Select my script (script not show)
Option Explicit
Public WithEvents objInbox As Outlook.Folder
Public WithEvents objInboxItems As Outlook.Items
Private Sub Application_Startup()
Set objInbox = Outlook.Application.Session.GetDefaultFolder(olFolderInbox)
Set objInboxItems = objInbox.Items
End Sub
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim objForward As Outlook.MailItem
Dim xStr1 As String
Dim xStr2 As String
If TypeOf Item Is MailItem Then
Set objMail = Item
If (objMail.SenderEmailAddress = "T#com") And (objMail.Subject = "ZZZZZ") Then
Set objForward = objMail.Forward
GoTo commonOutput
End If
End If
Exit Sub
commonOutput:
With objForward
.HTMLBody = xStr1 & xStr2 & Item.HTMLBody
.Display
End With
Release:
Set myFwd = Nothing
End Sub
VBA script which can be assigned to a rule should have the following signature:
Public Sub Test(item as object)
' your code
End Sub
Your existing code does almost the same without rules. It handles the ItemAdd event for the Inbox folder, so you just need to replace the Display method call with Send:
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
Dim objMail As Outlook.MailItem
Dim objForward As Outlook.MailItem
Dim xStr1 As String
Dim xStr2 As String
If TypeOf Item Is MailItem Then
Set objMail = Item
If (objMail.SenderEmailAddress = "T#com") And (objMail.Subject = "ZZZZZ") Then
Set objForward = objMail.Forward
GoTo commonOutput
End If
End If
Exit Sub
commonOutput:
With objForward
.HTMLBody = xStr1 & xStr2 & Item.HTMLBody
.Send
End With
Release:
Set myFwd = Nothing
End Sub

Move Email with ItemAdd

I'm attempting to move email with specific subject when received.
The mail is still in my Inbox. I've tested by sending mail from my account with specific subject.
Option Explicit
Private WithEvents inboxItems As Outlook.Items
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application
Dim objectNS As Outlook.NameSpace
Set outlookApp = Outlook.Application
Set objectNS = outlookApp.GetNamespace("MAPI")
Set inboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
Dim Msg As Outlook.MailItem
Set myInbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
If TypeName(item) = "MailItem" Then
Set Msg = item
If InStr(0, Msg.Subject, "Testing Subject", vbTextCompare) > 0 Then
Set fldr = Outlook.Session.GetDefaultFolder(olFolderInbox).Folders("Testing")
Msg.Move fldr
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
I created this macro in ThisOutlookSession.
I think you may have an error with the naming of your Sub which means it doesn't fire
Items_ItemAdd => inboxItems_ItemAdd
As an addendum: I recently implemented a RegEx filter to incoming e-mails as I found I couldn't easily use rules to filter out some junk e-mail coming my way. This should be able to adapted to your needs (I've added the rule I think should work for you, but it's untested)
Within the 'ThisOutlookSession'
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
On Error Resume Next
Call RegExFilterRules(EntryIDCollection)
End Sub
Within a module
Sub RegExFilterRules(ItemID As String)
' Requires Reference: Microsoft Scripting Runtime
Dim ThisNamespace As Outlook.NameSpace: Set ThisNamespace = Application.GetNamespace("MAPI")
Dim Inbox As Outlook.MAPIFolder: Set Inbox = ThisNamespace.GetDefaultFolder(olFolderInbox)
Dim Junk As Outlook.MAPIFolder: Set Junk = ThisNamespace.GetDefaultFolder(olFolderJunk)
Dim oMsg As Outlook.MailItem: Set oMsg = ThisNamespace.GetItemFromID(ItemID, Inbox.StoreID)
If Not oMsg Is Nothing And oMsg.Class = olMail Then
'If FindPattern(oMsg.Subject, "^M\d+$") Then oMsg.Move Junk ' oMsg.Delete
If FindPattern(oMsg.Subject, "^Testing Subject") Then oMsg.Move Inbox.Folders("Testing")
End If
End Sub
Private Function FindPattern(Str As String, Pattern As String) As Boolean
Dim RegEx As Object: Set RegEx = CreateObject("vbscript.RegExp")
With RegEx
.Global = True
.IgnoreCase = True
.MultiLine = True
.Pattern = Pattern
FindPattern = .Test(Str)
End With
End Function

How to initialize an event handler

I found this code online. It is supposed to auto populate my subject line with any attachments I provide. The code does not run.
I don't receive an error or anything that suggests its even going through the code.
Public WithEvents olInspectors As Outlook.Inspectors
Public WithEvents olMail As Outlook.MailItem
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Private Sub olInspectors_NewInspector(ByVal Inspector As Inspector)
Dim olItem As Object
Set olItem = Inspector.CurrentItem
If TypeName(olItem) = "MailItem" Then Set olMail = olItem
End Sub
Private Sub olMail_AttachmentAdd(ByVal Attachment As Attachment)
MsgBox "This is a test."
If olMail.Subject = "" Then
'If you don't want the prompt,
'Just delete the Msgbox line and its corresponding "End if".
If MsgBox("Do you want to use the attachment name as the subject", vbYesNo) = vbYes Then
olMail.Subject = Attachment.DisplayName
End If
End If
End Sub
There is nothing wrong with your code, you simply need to Initialize the Inspectors
Click on Sub Initialize_handlers() and press F5
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Or just use Application.Startup Event (Outlook), Save it and restart Outlook then it should work
Example
Public WithEvents olInspectors As Outlook.Inspectors
Public WithEvents olMail As Outlook.mailitem
Private Sub Application_Startup()
Set olInspectors = Application.Inspectors
End Sub
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Private Sub olInspectors_NewInspector(ByVal Inspector As Inspector)
Dim olItem As Object
Set olItem = Inspector.CurrentItem
If TypeName(olItem) = "MailItem" Then Set olMail = olItem
End Sub
Private Sub olMail_AttachmentAdd(ByVal Attachment As Attachment)
MsgBox "This is a test."
If olMail.Subject = "" Then
'If you don't want the prompt,
'Just delete the Msgbox line and its corresponding "End if".
If MsgBox("Do you want to use the attachment name as the subject", _
vbYesNo) = vbYes Then
olMail.Subject = Attachment.DisplayName
End If
End If
End Sub