I would like to be able to create a task from a Sent email in Outlook at the time of sending. It is find if a button pops up asking me if I want a task, and I have to click Yes or No. I found the code below. But if I click Yes, it creates the task without me editing it. I just want the Task window to pop up with the email I sent populating it, but I want to add the dates etc. Can anyone help please?
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'Updated by Extendoffice 20181123
Dim xYesNo As Integer
Dim xPrompt As String
Dim xTaskItem As TaskItem
Dim xRecipient As String
On Error Resume Next
xPrompt = "Do you want to create a task for this message?"
xYesNo = MsgBox(xPrompt, vbYesNo + vbInformation, "Kutools for Outlook")
Cancel = False
If xYesNo = vbNo Then Exit Sub
Set xTaskItem = Application.CreateItem(olTaskItem)
For Each Rcp In Item.Recipients
If xRecipient = "" Then
xRecipient = Rcp.Address
Else
xRecipient = xRecipient & vbCrLf & Rcp.Address
End If
Next Rcp
xRecipient = xRecipient & vbCrLf & Item.Body
With xTaskItem
.Subject = Item.Subject
.StartDate = Item.ReceivedTime
.DueDate = Date + 3 + CDate("9:00:00 AM")
.ReminderSet = True
.ReminderTime = Date + 2 + CDate("9:00:00 AM")
.Body = xRecipient
.Save
End With
Set xTaskItem = Nothing
End Sub
You need to call the Display method if you need to show an Outlook inspector window for editing task properties:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'Updated by Extendoffice 20181123
Dim xYesNo As Integer
Dim xPrompt As String
Dim xTaskItem As TaskItem
Dim xRecipient As String
On Error Resume Next
xPrompt = "Do you want to create a task for this message?"
xYesNo = MsgBox(xPrompt, vbYesNo + vbInformation, "Kutools for Outlook")
Cancel = False
If xYesNo = vbNo Then Exit Sub
Set xTaskItem = Application.CreateItem(olTaskItem)
For Each Rcp In Item.Recipients
If xRecipient = "" Then
xRecipient = Rcp.Address
Else
xRecipient = xRecipient & vbCrLf & Rcp.Address
End If
Next Rcp
xRecipient = xRecipient & vbCrLf & Item.Body
With xTaskItem
.Subject = Item.Subject
.StartDate = Item.ReceivedTime
.DueDate = Date + 3 + CDate("9:00:00 AM")
.ReminderSet = True
.ReminderTime = Date + 2 + CDate("9:00:00 AM")
.Body = xRecipient
.Display
End With
Set xTaskItem = Nothing
End Sub
In that case the original window should be closed and the email is sent out. But you will get the task item window opened for editing its properties. If you need to delay the send process until you are done with task properties editing process you may pass true to the Display method to stop the execution of the ItemSend event handler and wait until the dialog window is closed.
Related
I have an "Oh Shi-" rule, that delays the delivery of my emails by 5 minutes.
I disable this rule whenever I want the email to reach the recipient as fast as possible. The rule is re-enabled after the email is sent.
The macro is triggered via a button on the "Message" ribbon.
Sometimes the email will be sent right away.
Sometimes the email will sit in the outbox. If I check under Options Ribbon → Delay Delivery, there is a 5 minutes delay set. The 5-min rule should have been disabled.
Below is my code:
Sub OhShi()
Dim olRules As Outlook.Rules
Dim olRule As Outlook.Rule
Dim intCount As Integer
Dim blnExecute As Boolean
Dim objApp As Outlook.Application
Set objApp = Application
Dim answer As VbMsgBoxResult
answer = MsgBox("Are you sure you want to fast-send the email?", vbYesNoCancel + vbQuestion + vbDefaultButton1, "The OhShi- rule is being disabled!")
If answer = vbYes Then
Cancel = False
ElseIf answer = vbNo Then
Cancel = True
Else
Cancel = True
End If
If Cancel = False Then
'disable the rule
Set olRules = Application.Session.DefaultStore.GetRules
Set olRule = olRules.Item("Delay Delivery 5min")
olRule.Enabled = False
If blnExecute Then olRule.Execute ShowProgress:=True
olRules.Save
'check if rule was indeed disabled
If olRule.Enabled = False Then
'send active email
Set objItem = objApp.ActiveInspector.CurrentItem
objItem.Send
Else
MsgBox "The script failed successfully!", vbCritical
End If
'reenable the rule
olRule.Enabled = True
If blnExecute Then olRule.Execute ShowProgress:=True
olRules.Save
Set olRules = Nothing
Set olRule = Nothing
Set objItem = Nothing
End If
End Sub
I have just tried to remove the part of the code which re-enables the Rule, but the Rule is still being applied to the email. After the code is run I can verify now that the rule was indeed disabled, but it still gets applied to the email.
If disabling the rule is ignored, possibly something is not synchronized when the item is sent.
Waiting before sending may increase reliability.
Sub disableRule()
Dim olRules As Rules
Dim olRuleName As String
Dim olRule As Rule
Dim objItem As Object
Dim answer As VbMsgBoxResult
Dim msg As String
Set olRules = Session.defaultStore.GetRules
olRuleName = "Delay Delivery 5min"
Set olRule = olRules.Item(olRuleName)
Set objItem = ActiveInspector.currentItem
answer = MsgBox("Are you sure you want to fast-send the email?", _
vbOKCancel + vbQuestion + vbDefaultButton2, _
"The " & olRuleName & " rule is being disabled!")
If answer = vbOK Then
' disable the rule
olRule.Enabled = False
olRules.Save
Debug.Print vbCr & "Rule disabled."
' If synching is the cause
Dim waitTime As Long
Dim delay As Date
' If it can takes minutes, occasionally failing to send fast may be preferable.
waitTime = 3 ' in seconds - adjust as needed
Debug.Print vbCr & "Wait start: " & Now
delay = DateAdd("s", waitTime, Now)
Debug.Print "Wait until: " & delay
Do Until Now > delay
DoEvents
Loop
Debug.Print "Wait end..: " & Now
Debug.Print "At least " & waitTime & " seconds delay to allow a synch someplace."
' send active email
objItem.Send
Debug.Print vbCr & "objItem.Send"
msg = "Item sent with disabled rule possiby synched."
Debug.Print msg
MsgBox msg, vbInformation
olRule.Enabled = True
olRules.Save
Debug.Print vbCr & "Rule re-enabled."
Else
msg = "Item not sent."
Debug.Print msg
MsgBox msg, vbInformation
End If
Debug.Print "Done."
End Sub
In the code below I don’t understand how the subroutine checks if the emails coming through are a reply of an email previously sent.
The first subroutine seems to check if the subject line of an incoming email matches this condition: "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject)
After that I am confused. The only way the code works for me is by using categories. It does not work as shown below.
Public WithEvents objInboxItems As Outlook.Items
Private Sub Application_Startup()
Set objInboxItems = Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
'If receive the reply, clear the flag and remove the reminder
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
Dim objSentItems As Outlook.Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Dim dSendTime As String
Set objSentItems = Outlook.Application.Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olMail Then
For i = 1 To objSentItems.Count
If objSentItems.Item(i).Class = olMail And **objSentItems.Item(i).categories = "Not Completed"** Then
Set objVariant = objSentItems.Item(i)
strSubject = LCase(objVariant.Subject)
dSendTime = objVariant.SentOn
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
If Item.SentOn > dSendTime Then
With objVariant
.ClearTaskFlag
.ReminderSet = False
.Save
End With
End If
End If
End If
Next i
End If
End Sub
'Get a prompt asking if to send a notification email
Private Sub Application_Reminder(ByVal Item As Object)
Dim strPrompt As String
Dim nResponse As Integer
Dim objFollowUpMail As Outlook.MailItem
'You can change the subject as per your real case
If (Item.Class = olMail) And (LCase(Item.Subject) = "datanumen outlook repair") Then
strPrompt = "You haven't yet recieved the reply of " & Chr(34) & Item.Subject & Chr(34) & " within your expected time. Do you want to send a follow-up notification email?"
nResponse = MsgBox(strPrompt, vbYesNo + vbQuestion, "Confirm to Send a Follow-Up Notification Email")
If nResponse = vbYes Then
Set objFollowUpMail = Application.CreateItem(olMailItem)
With objFollowUpMail
.To = Item.Recipients.Item(1).Address
.Subject = "Follow Up: " & Chr(34) & Item.Subject & Chr(34)
.Body = "Please respond to my email " & Chr(34) & Item.Subject & Chr(34) & "as soon as possible"
.attachments.Add Item
.Display
End With
End If
End If
End Sub
The code just needs better commenting. The basic logic is: When a new email comes in, check if it's a reply to any email in the sent box. If so, remove the task and reminder flags from the sent email.
Public WithEvents objInboxItems As Outlook.Items
Private Sub Application_Startup()
Set objInboxItems = Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
'If receive the reply, clear the flag and remove the reminder
Private Sub objInboxItems_ItemAdd(ByVal Item As Object) 'New item received in inbox
Dim objSentItems As Outlook.Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Dim dSendTime As String
' get all emails in sent box
Set objSentItems = Outlook.Application.Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olMail Then 'if new inbox item is email
For i = 1 To objSentItems.Count 'for each item in sent box
If objSentItems.Item(i).Class = olMail Then ' if sent item is email
Set objVariant = objSentItems.Item(i) 'sent email
strSubject = LCase(objVariant.Subject) 'sent email subject
dSendTime = objVariant.SentOn 'sent email send date
'Check subject, if new email is reply to sent email, or new email subject contains sent email subject
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
If Item.SentOn > dSendTime Then ' if new email has later send date then sent email (else can't be reply)
With objVariant 'with sent email
.ClearTaskFlag ' clear flag
.ReminderSet = False 'remove reminder
.Save
End With
End If
End If
End If
Next i
End If
End Sub
The code listed above is badly written and wrong in general. The ItemAdd event is fired when an item is added to the folder, not received. For example, a user may move some items from one folder to another triggering this event. If you want to handle all incoming emails you need to handle the NewMailEx event of the Application class which is fired when a new message arrives in the Inbox and before client rule processing occurs. You can use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item.
For i = 1 To objSentItems.Count 'for each item in sent box
If objSentItems.Item(i).Class = olMail Then ' if sent item is email
Instead of interating over all items in the folder and finding items that correspond to your conditions I'd recommend using the Find/FindNext or Restrict methods of the Items class. 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
I tried to recreate the situation, given flags are not reliable in my setup.
It may be possible to remove reminders by reinitializing ReminderTime.
Code for ThisOutlookSession
Option Explicit
Public WithEvents objInboxItems As Items
Private Sub Application_Startup()
Set objInboxItems = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub test_objInboxItems_ItemAdd()
' For testing select a reply to the flagged sent item
objInboxItems_ItemAdd ActiveExplorer.Selection(1)
End Sub
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
' If reply received,
' clear the flag and remove the reminder from the corresponding sent item
' No attempt to make the logic efficient
' - Find / Restrict in the sent items folder
' In my setup
' - TaskDueDate is always 4501-01-01 (no date)
' - Reminders on mailitems are not functional
Dim objSentItems As Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Set objSentItems = Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olmail Then
Debug.Print
Debug.Print "Item.Subject ...........: " & Item.Subject
For i = 1 To objSentItems.Count
If objSentItems.Item(i).Class = olmail Then
Set objVariant = objSentItems.Item(i)
strSubject = LCase(objVariant.Subject)
If objVariant.ReminderTime <> "4501-01-01" Then
Debug.Print " strSubject ............: " & strSubject
Debug.Print " objVariant.SentOn .....: " & objVariant.SentOn
Debug.Print " objVariant.ReminderTime: " & objVariant.ReminderTime
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
'Debug.Print " Item.SentOn .....: " & Item.SentOn
'Debug.Print " objVariant.SentOn: " & objVariant.SentOn
If Item.SentOn > objVariant.SentOn Then
Debug.Print " * strSubject ......: " & strSubject
Debug.Print " * Item.SentOn .....: " & Item.SentOn
Debug.Print " * objVariant.SentOn: " & objVariant.SentOn
If Now > objVariant.ReminderTime Then
With objVariant
' remove flag
.ClearTaskFlag
' attempt to remove reminder
.ReminderSet = False
' reinitializing ReminderTime may have an impact
.ReminderTime = "4501-01-01"
.Save
Debug.Print " ** Flag removed."
Debug.Print " ** Reminder removal attempted."
End With
End If
End If
Else
Debug.Print " *** subject does not match"
End If
End If
End If
Next i
End If
Debug.Print "done"
End Sub
Private Sub test_ToggleMarkAsTaskFlagAndSetReminder()
' for testing
' select a mailitem in the sent items folder to add a flag and a reminder
ToggleMarkAsTaskFlagAndSetReminder ActiveExplorer.Selection(1)
End Sub
Private Sub ToggleMarkAsTaskFlagAndSetReminder(ByVal objItem As Object)
' In my setup
' - TaskDueDate is always 4501-01-01 (no date)
' - Reminders on mailitems are not functional
If TypeOf objItem Is MailItem Then
Debug.Print
Debug.Print "objItem.Subject .............: " & objItem.Subject
Debug.Print " objItem.TaskDueDate Current: " & objItem.TaskDueDate
Debug.Print " objItem.ReminderTime Current: " & objItem.ReminderTime
' https://learn.microsoft.com/en-us/office/vba/api/outlook.olmarkinterval
If objItem.IsMarkedAsTask = False Then
objItem.MarkAsTask (olMarkThisWeek)
Debug.Print " * Marked as task"
' In my setup - TaskDueDate is always 4501-01-01
Debug.Print " objItem.TaskDueDate Updated?: " & objItem.TaskDueDate
Debug.Print " objItem.ReminderTime Updated?: " & objItem.ReminderTime
' In my setup - Reminders on mailitems are not functional
Debug.Print " objItem.ReminderSet Current: " & objItem.ReminderSet
objItem.ReminderSet = True
Debug.Print " objItem.ReminderSet Updated: " & objItem.ReminderSet
objItem.ReminderTime = DateAdd("d", -7, Now) ' testing
Debug.Print " objItem.ReminderTime Updated: " & objItem.ReminderTime
Else 'Reinitialize item
objItem.ClearTaskFlag
Debug.Print " * Task cleared"
' TaskDueDate not functional in my setup, remains 4501-01-01
Debug.Print " objItem.TaskDueDate Updated?: " & objItem.TaskDueDate
objItem.ReminderSet = False
Debug.Print " objItem.ReminderSet = False"
objItem.ReminderTime = "4501-01-01"
Debug.Print " objItem.ReminderTime Updated: " & objItem.ReminderTime
End If
'objItem.Display
objItem.Save
Else
Debug.Print "not a mailitem"
End If
End Sub
I want to apply HTML when a user prepares email with a default template.
I got some basic code online:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
On Error Resume Next
If InStr(LCase(Item.To), "xxx#gmail.com") Then
prompt$ = "Are You Sure want to send this email to " & Item.To& " ?"
If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbNo Then
Cancel = True
Dim objOutlookMsg As Outlook.MailItem
Set objOutlookMsg = Outlook.Application.CreateItem(olMailItem)
objOutlookMsg.HTMLBody = "<html><body><strong>HELLO OUTLOOK</strong></body></html>"
objOutlookMsg.Display
End If
End If
End Sub
When I send, a new message window opens.
I want that HTML to present in the same window, not a new window.
The Item.To Property Returns String list of display names, what you need it Recipient.Address Property which will Return a String representing the email address of the Recipient.
Also check If Item.Class <> olMail if not then Exit Sub
Full Example
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If Item.Class <> olMail Then Exit Sub
Dim Rcpt As Recipient
Dim Prompt As String
Prompt = "Are You Sure want to send this email to " & Item.To & " ?"
For Each Rcpt In Item.Recipients
If InStr(1, Rcpt.AddressEntry, "TEST#gmail.com", vbTextCompare) Then
If MsgBox(Prompt, vbYesNo + vbQuestion + vbMsgBoxSetForeground, _
"Check Address ") = vbNo Then
Cancel = True
Exit Sub
End If
Item.HTMLBody = "<html><body><strong>HELLO OUTLOOK</strong></body></html>" _
& Item.HTMLBody
End If
Next
End Sub
Updated per comments
Simply remove if MsgBox end if block of code
Example
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If Item.Class <> olMail Then Exit Sub
Dim Rcpt As Recipient
For Each Rcpt In Item.Recipients
If InStr(1, Rcpt.AddressEntry, "TEST#gmail.com", vbTextCompare) Then
Item.HTMLBody = "<html><body><strong>HELLO OUTLOOK</strong></body></html>" _
& Item.HTMLBody
End If
Next
End Sub
If you want to modify the HTML body of the message begin sent (it is passed as the Item parameter to your event handler), why are you creating a new message instead of modifying the existing message? Set HTMLBody property on the Item object.
I want to validate that the outgoing email is correctly attached with a correct file. The email subject contains a code. The attachment filename is automatically generated with a code and attached manually to the email. The VBA is to check whether the email subject contains a common pattern in the filename of the attachment.
The code is like H??#######, i.e. it must start with "H", followed with 2 letters, and then 7 digits.
If both the email subject and filename contain the same code, the email is allowed to send, otherwise it should warn. For example:
Subject: Urgent Chapter 10 - HCX1234567 updated on 12 Dec 2015
Filename: HCX1234567_ABCCh10_20151212_0408
This email is allowed.
Is it possible to do such validation before sending?
Here is my attempt:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
'Create Geoff Lai on 14 March 2016
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim pa As Outlook.PropertyAccessor
Dim prompt As String
Dim strMsg As String
Dim mailContent As String
Dim jobCode As String
Dim attachName As String
Dim pos As Integer
Dim jcodepos As Integer
Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
attachName = Item.Attachments.Item(1).FileName
mailContent = Item.Body + Item.Subject ' Get a copy of all the e-mail body text and subject text to search.
mailContent = LCase(mailContent) ' Make whole string lowercase for easier searching.
Set recips = Item.Recipients
For Each recip In recips 'Record email addressees if send to external domain
Set pa = recip.PropertyAccessor
If InStr(LCase(pa.GetProperty(PR_SMTP_ADDRESS)), "#mydomain.com") = 0 Then
strMsg = strMsg & " " & pa.GetProperty(PR_SMTP_ADDRESS) & vbNewLine
End If
Next
If strMsg <> "" Then
If (Item.Attachments.Count = 0) Then ' Check attachment
If InStr(1, mailContent, "attach") > 0 Then
pos = 1
ElseIf InStr(1, mailContent, "Attach") > 0 Then
pos = 1
ElseIf InStr(1, mailContent, "enclose") > 0 Then
pos = 1
ElseIf InStr(1, mailContent, "Enclose") > 0 Then
pos = 1
Else: pos = 0
End If
End If
If (pos > 0) Then 'If there is no attachment:
If MsgBox("With the word attach or enclose, attachment should be found in this email" & vbNewLine & "Please Confirm.", vbYesNo + vbCritical + vbMsgBoxSetForeground, "Missing Attachment") = vbYes Then
prompt = "This email will be sent outside of mydomain.com to:" & vbNewLine & strMsg & "Do you want to proceed?"
If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then
Cancel = True
Exit Sub
Else
Exit Sub
End If
Else
Cancel = True 'Stop sending
End If
End If
If (Item.Attachments.Count > 0) Then ' Validate attachment and subject
jcodepos = InStr(1, attachName, "H??#######", 0) ' Get job code position
jobCode = Mid(attachName, jcodepos, 10) ' Get job code
If (InStr(1, Item.Subject, jobCode, 0) = 0) Then ' If no common code between subject and attachment
If MsgBox("There is no common job code between the email subject and the filename of the attachment." & vbNewLine & "Do you want to proceed?", _
vbYesNo + vbCritical + vbMsgBoxSetForeground, "Wrong Attachment?") = vbNo Then
Cancel = True
Exit Sub
Else
Exit Sub
End If
ElseIf MsgBox("Common job code " & jobCode & " is found in the email subject and the filename of the attachment" & prompt, _
vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Confirm Job Code") = vbNo Then ' If common code is found
Cancel = True
Exit Sub
Else
Exit Sub
End If
End If
End If
End Sub
However, I get an error at jobCode = Mid(attachName, jcodepos, 10), which is:
Run-time error '5' Invalid procedure call or argument
Application_ItemSend, the usual way, in ThisOutlookModule. How can I automatically run a macro when an email is sent in Outlook?
In the VB editor set the reference to Regular Expressions.
Similar to the code in the Question part of Regular Expression Rules in Outlook 2007?. Check RegEx.Pattern = "(H[A-Z]{2}[0-9]{7})" against the filename. Continue with RegEx or InStr to verify the subject includes the filename match.
Since you thinking about using VBA I would assume that you are using Outlook as your email client. If so, please add this to your question and the tags. With this assumption the answer is that it depends:
If Outlook is actually used to send the email then it can be done. The following Q&A is probably a good starting point.
how to check details before sending mails in outlook using macros?
Yet, the above technique will not work if the email is created with File | Send commands in Office programs or similar commands in Windows Explorer or other programs.
Finally, I have figured it out, Thanks for the advices!
Here is my workout.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim pa As Outlook.PropertyAccessor
Dim regex As Object, codeInSubject As Object, codeInAttach As Object
Dim matchSbjtCode As String, matchAttchcode As String
Dim prompt As String
Dim strMsg As String
Dim mailContent As String
Dim attachName As String
Dim pos As Integer
Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
Set regex = CreateObject("vbScript.regExp")
With regex
.Pattern = "[H][ACDILNOPQTUVW][BCGJMOPRSTWY][1-9][0-9]{6}" ' Set regular expression pattern
.Global = False ' Check the first instance only
End With
attachName = Item.Attachments.Item(1).FileName
mailContent = Item.Body + Item.Subject ' Get a copy of all the e-mail body text and subject text to search.
mailContent = LCase(mailContent) ' Make whole string lowercase for easier searching.
Set recips = Item.Recipients
For Each recip In recips 'Record email addressees if send to external domain
Set pa = recip.PropertyAccessor
If InStr(LCase(pa.GetProperty(PR_SMTP_ADDRESS)), "#mydomain.com") = 0 Then
strMsg = strMsg & " " & pa.GetProperty(PR_SMTP_ADDRESS) & vbNewLine
End If
Next
prompt = "This email will be sent outside of mydomain.com to:" & vbNewLine & strMsg & "Do you want to proceed?"
If strMsg <> "" Then
If (Item.Attachments.Count = 0) Then ' Check attachment
If InStr(1, mailContent, "attach") > 0 Then
pos = 1
ElseIf InStr(1, mailContent, "enclose") > 0 Then
Else: pos = 0
End If
End If
If (pos > 0) Then 'If there is no attachment:
If MsgBox("With the word 'attach' or 'enclose', attachment should be found in this email" & vbNewLine & _
"Please Confirm.", vbYesNo + vbCritical + vbMsgBoxSetForeground, "Missing Attachment") = vbYes Then ' Prompt to check
If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then
Cancel = True
Exit Sub
Else
Exit Sub
End If
Else
Cancel = True 'Stop sending
End If
End If
If (Item.Attachments.Count > 0) Then ' Validate attachment and subject
If regex.test(Item.Subject) And regex.test(attachName) Then ' Test the job codes in the email subject and attachment filename
Set codeInSubject = regex.Execute(Item.Subject)
Set codeInAttach = regex.Execute(attachName)
If StrComp(codeInSubject(0), codeInAttach(0)) = 0 Then ' Compare the codes found
If MsgBox("Common job code """ & codeInAttach(0) & """ is found in the email subject and the filename of the attachment. " & vbNewLine & prompt, _
vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Confirm Job Code") = vbNo Then ' If found, confirm to send
Cancel = True
Else: Exit Sub
End If
ElseIf MsgBox("There is no common job code between the email subject and the filename of the attachment." & vbNewLine & _
"Do you want to DISCARD?", vbYesNo + vbCritical + vbMsgBoxSetForeground, "Wrong Attachment?") = vbYes Then ' if not found, discard
Cancel = True
Else: Exit Sub
End If
End If
End If
End If
End Sub
When I close and relaunch Outlook the macro doesn't work.
This code will validate before sending the mail in Outlook for subject and attachments.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim lngAns As Long
Dim varArray As Variant
Dim strWordFound As String
varArray = Array("PFA", "Attached", "Enclosed", "File", "Report")
For lngCount = LBound(varArray) To UBound(varArray)
If InStr(1, Item.Body, varArray(lngCount), vbTextCompare) Or InStr(1, Item.Subject, varArray(lngCount), vbTextCompare) Then
strWordFound = strWordFound & "," & varArray(lngCount)
End If
Next
strWordFound = Mid(strWordFound, 2)
If Len(strWordFound) > 0 And Item.Attachments.Count = 0 Then
If MsgBox("Found No Attachments but the Word(s): " & _
strWordFound & vbTab & vbCr & "Do you want to send the mail anyway?", _
vbYesNo + vbQuestion, "Attachment Missing") = vbNo Then Cancel = True
End If
If Len(Trim(Item.Subject)) = 0 Then
If MsgBox("Subject is Empty. Are you sure you want to send the Mail?", _
vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Subject Missing") = vbNo Then Cancel = True
End If
End Sub
Update Macro Security settings in the Trust Center.
Some links:
Enable or disable macros in Office documents
Outlook 2013 & 2010: Enable or Disable Macros