VBA code not running on Outlook restart - vba

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

Related

VBA code to create a task when sending emails

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.

Email recipient name verification [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 10 months ago.
This post was edited and submitted for review 10 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
There is a tool in outlook that notifies a sender about possible missing attachments as they click the send button. This tool seems to search the body of the email for keywords like "attachment" and then check to see if anything is attached to the email. If not, the notification then pops up.
I'm looking for something similar but a bit more advanced. I would like a similar notification pop-up to appear when the body of my email does not contain neither the first name nor the last name of my recipient(s).
EDIT / UPDATE
I have eventually created my own VBA code to solve this problem, based on FaneDuru's answer. Please consider unclosing this question.
Note: my code searches for either the first, middle(s) or last name of each one of the recipients, but only on the first two lines of the body of the email.
If any one of these searches is successful (i.e. if the name is found on the first 2 lines), then the check is successful and the email can be sent, otherwise the sender is notified.
When the recipient's email address is not in the address book of the sender, the programme does other similar things that can be easily seen in the code.
Please feel free to suggest improvements.
Option Explicit
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If TypeName(Item) = "MailItem" Then
Dim myMail As MailItem, recip As Recipient, strNoRef As String, msg As VbMsgBoxResult, msge As VbMsgBoxResult, noEntry As String
Dim i As Integer
Dim j As Integer
Dim Lines() As String
Dim fLines As String
i = 0
j = 0
Set myMail = Item
Lines = Split(myMail.Body, vbCrLf, 4)
fLines = Lines(0) & Lines(1) & Lines(2)
For Each recip In myMail.Recipients
If recip.Address <> recip.AddressEntry Then
i = i + 1
If Not NameExists(recip.AddressEntry, fLines) Then
j = j + 1
strNoRef = strNoRef & recip.AddressEntry & vbCrLf
End If
End If
Next
For Each recip In myMail.Recipients
If Not recip.Address <> recip.AddressEntry Then
noEntry = noEntry & recip.AddressEntry & vbCrLf
End If
Next
If j = i And noEntry = "" Then
msg = MsgBox("This mail does not contain a reference to anyone of the following:" & vbCrLf & _
vbCrLf & strNoRef & vbCrLf & _
"To send the mail anyway, please press ""Yes"".", vbYesNo, "Send the mail?")
If msg <> vbYes Then Cancel = True
End If
If j = i And noEntry <> "" Then
msg = MsgBox("This mail does not contain a reference to anyone of the following:" & vbCrLf & _
vbCrLf & strNoRef & vbCrLf & _
"And the following recipients are not in the address book:" & vbCrLf & _
vbCrLf & noEntry & vbCrLf & _
"To send the mail anyway, please press ""Yes"".", vbYesNo, "Send the mail?")
If msg <> vbYes Then Cancel = True
End If
If noEntry <> "" And j < i Then
msge = MsgBox("The following recipients are not in the address book:" & vbCrLf & _
vbCrLf & noEntry & vbCrLf & "So, the email was not sent." & vbCrLf & _
"To send it, please press ""Yes"".", vbYesNo, "Send the mail?")
If msge <> vbYes Then Cancel = True
End If
If noEntry = "" And j < i Then
Cancel = False
End If
End If
End Sub
Function NameExists(strName As String, strBody As String) As Boolean
Dim arrName, El
arrName = Split(strName, " ")
For Each El In arrName
If InStr(1, strBody, El, vbBinaryCompare) > 0 Then
NameExists = True: Exit Function
End If
Next El
End Function
In order to achieve what you try explaining, please proceed in the next way:
Change Outlook security settings to make it open with Macro Enabled:
File - Options - Trust Center - Trust Center Settings... - Macro Settings and choose Notifications for all Macros, or Enable All Macros (not recommended.... Press 'OK', of course...
Close and reopen Outlook, choosing Enable Macros!
Press F11 in order to access VBE (Visual Basic for Applications) window. In its left pane you will see Project1 (VBAProject.OTM).
Expand Microsoft Outlook Objects and double click on ThisOutlookSession.
In the opening window (to the right side), please copy the next code:
Option Explicit
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If TypeName(Item) = "MailItem" Then
Dim myMail As MailItem, recip As Recipient, strNoRef As String, msg As VbMsgBoxResult, noEntry As String
Set myMail = Item 'just to benefit of intellisense suggestions...
For Each recip In myMail.Recipients 'iterate between mail recipients
If recip.Address <> recip.AddressEntry Then 'if the address has a name (not only xxx#domain.com):
If Not NameExists(recip.AddressEntry, myMail.Body) Then 'check if one of its names (first or last) exists
strNoRef = strNoRef & recip.AddressEntry & vbCrLf 'if not, build a string to be used in the message
End If
Else
noEntry = noEntry & recip.AddressEntry & vbCrLf
End If
Next
If noEntry <> "" Then
MsgBox "The following recipients are not in the address book:" & vbCrLf & _
vbCrLf & noEntry
End If
If strNoRef <> "" Then
msg = MsgBox("The mail you try sending does not contain a reference to" & vbCrLf & _
vbCrLf & strNoRef & vbCrLf & "and it cannot be sent..." & vbCrLf & _
"To send it as it is, please press ""Yes"".", vbYesNo, "Send the mail?")
If msg <> vbYes Then Cancel = True 'if not pressing "Yes", the sending will be cancelled
End If
End If
End Sub
Function NameExists(strName As String, strBody As String) As Boolean
Dim arrName, El
arrName = Split(strName, " ")
For Each El In arrName
If InStr(1, strBody, El, vbBinaryCompare) > 0 Then
NameExists = True: Exit Function
End If
Next El
End Function
It would be good to press Save on the VBE Standard toolbar. I thing Ctrl + S will also work...
Try playing with mails and send some feedback...

Windows 10 / Office 2016 - Selected item is not attaching when I run my macro

For some reason, I can't get the selected item which would be an email from my inbox to attach as an attachment when I create a new mail from my macro. I'm using Windows 10 / Outlook 2016. I had this working in Windows 7 Office 2010, but I'm not sure why it's not working now. Any help would be greatly appreciated.
Sub SendEmail()
Dim Inbox As Object
Dim MyItem As Object
Dim AddEmail As Boolean
Dim i As Long
Dim iAnswer As VbMsgBoxResult
'Check if User wants to copy an existing email to new form
iAnswer = MsgBox(Prompt:=" Do you want to copy the selected email to new form? (If you select YES, Keep the current email selected - DO NOT SELECT ANOTHER EMAIL - Until you finish sending)", _
Buttons:=vbYesNo, Title:="Copy Selected Email")
If iAnswer = vbYes Then
AddEmail = True
End If
'Check Version of Outlook (2007 vs 2010)
If Outlook.Application.Version = "12.0.0.6680" Then
On Error GoTo FolderError:
Set Inbox = Outlook.Application.GetNamespace("MAPI").Folders("Mailbox - #Incoming_Workshare")
On Error Resume Next
Else
On Error GoTo FolderError:
Set Inbox = Outlook.Application.GetNamespace("MAPI").Folders("#Incoming_Workshare")
On Error Resume Next
End If
'Open Form From Folder (The Inbox =)
Set MyItem = Inbox.Items.Add("IPM.Note.Workflow Sharing 2016")
MyItem.Display
MyItem.Subject = "Automatically Generated Based on Job Information"
'Check Version of VBA and Form to make sure you are using latest macro
If Not MyItem.Mileage = 11 Then
'Check if User wants to copy an existing email to new form
iAnswer = MsgBox(Prompt:="ALERT - Macro has been updated - Select Yes to Update" & vbCrLf & "(Note: Outlook will be restarted)", _
Buttons:=vbYesNo, Title:="Automatic Macro Update")
If iAnswer = vbYes Then
Shell "wscript C:\Macro\UpdateOutlookMacro.vbs", vbNormalFocus
End If
End If
'Copy Selected Emails to New Email if you selected Yes
If AddEmail = True Then
'Check if a there is a reference to the long access time projects in the subject or body to add instructions to also send as attachment (LARGE PROJECTS)
If InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "TUCAN") > 0 Or _
InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "RUDY") > 0 Or _
InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "SARGENT") > 0 Then
MyItem.HTMLBody = "<b>Additional Instructions from Originating Location:</b>" & Chr(11) & "PLEASE SEND BACK HYPERLINKS AND ATTACHMENTS FOR ALL EDITED FILES" & Chr(11) & Chr(11) & Chr(11) & Chr(11) & "---------------------------------------------" & Chr(11) & "Original Banker Email:" & Chr(11)
Else
MyItem.HTMLBody = "<b>Additional Instructions from Originating Location:</b>" & Chr(11) & Chr(11) & Chr(11) & Chr(11) & Chr(11) & "---------------------------------------------" & Chr(11) & "Original Banker Email:" & Chr(11)
End If
MyItem.BodyFormat = olFormatRichText
'Check large job 15MB
If (ActiveExplorer().Selection.Item(1).Size >= 15728640) Then
MsgBox "Alert! The attached original email size is " & Format(ActiveExplorer().Selection.Item(1).Size / 1048576, 0#) & " MBs. There are errors when sending large emails. Please save attachments as links to reduce the filesize.", , Title:="Email Size Too Big"
End If
MyItem.Attachments.Add ActiveExplorer().Selection.Item(1)
'Check if Sender is an autoforward from a mailbox, alerting to be manually updated
MyItem.UserProperties("Clocker") = ActiveExplorer().Selection.Item(1).SenderName + "; " + ActiveExplorer().Selection.Item(1).CC
If MyItem.UserProperties("Clocker") = "OH Mail; " Or MyItem.UserProperties("Clocker") = "NO Mail; " Or MyItem.UserProperties("Clocker") = "LAV Mail; " Or MyItem.UserProperties("Clocker") = "OK Mail; " Or MyItem.UserProperties("Clocker") = "WY Mail; " Then
'MsgBox "Alert! Please populate the Requestor/Clocker field. It cannot be listed as the Advisory Presentation Mailbox"
'MyItem.UserProperties("Clocker") = "" ' Removed Q4
Dim CorrectedClocker1, CorrectedClocker2, CorrectedClocker3 As String
Correctedclocker1 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "From:", "Sent:"))
If InStr(ActiveExplorer().Selection.Item(1).body, "Cc:") > 0 Then
CorrectedClocker2 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "To:", "Cc:"))
CorrectedClocker3 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "Cc:", "Subject:"))
Else
CorrectedClocker2 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "To:", "Subject:"))
CorrectedClocker3 = ""
End If
CorrectedClocker2 = Replace(CorrectedClocker2, "#Completed", "")
CorrectedClocker3 = Replace(CorrectedClocker3, "#Completed", "")
MyItem.UserProperties("Clocker") = CorrectedClocker1 & "; " & CorrectedClocker2 & "; " & CorrectedClocker3
Else
If InStr(MyItem.UserProperties("Clocker"), "[Cvcs]") > 0 Then
Is this running inside Outlook VBA?. Should Attachments.Add line be the following?
MyItem.Attachments.Add Outlook.Application.ActiveExplorer.Selection.Item(1)
Get rid of the "On Error Resume Next" statements - they are hiding runtime errors.
If you want to add a mailbox item as an attachment to a new message.
You need to set the Outlook.OlAttachmentType property to olEmbeddeditem.
You can add a mail item as an attachment by referring to the code below.
Sub ResolveName()
Dim myItem As Object
Dim Item As Object
Dim myFolder As Folder
Set myNamespace = Application.GetNamespace("MAPI")
Set myFolder = myNamespace.GetDefaultFolder(olFolderInbox)
Set myItem = Application.CreateItem(olMailItem)
Set Item = myFolder.Items(2)
'Item.Display
myItem.Attachments.Add Item, Outlook.OlAttachmentType.olEmbeddeditem, 1, "first"
myItem.Display
End Sub

VBA: Find whether there is common pattern between the email subject and attachment name

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

VBA Outlook Script

I have a script I've pieced together over time. Recently a plugin we need to use in Outlook has caused some issues. Basically we get prompted twice because when the plugin is used the e-mail ends up being destroyed and re-created with a specific attachment filename. At this point the user is prompted again. I've tried to work in a For loop to skip the script if it finds this attachment. However, when I added the For loop it just seems to skip the entire script. I have limited experience with VBA and so I'm sure it's an issue with my syntax or usage. See script below:
Private Sub Application_ItemSend _
(ByVal Item As Object, Cancel As Boolean)
Dim strMsg As String
Dim Atmt As Variant
'strMsg = Item.Class
If Item.Class = "43" Then
For Each Atmt In Item.Attachments
If VBA.Right(Atmt.FileName, 3) = ".sf" Then
GoTo NonEmailError
End If
Next Atmt
If Item.CC = "" Then
strMsg = "To recipients: " & Item.To & vbCrLf & _
"Are you sure you want to send this message?"
Else
strMsg = "To recipients: " & Item.To & vbCrLf & _
"Cc recipients: " & Item.CC & vbCrLf & _
"Bcc recipients: " & Item.BCC & vbCrLf & _
"Are you sure you want to send this message?"
End If
Else
GoTo NonEmailError
End If
' Exit Sub
' Ignore errors for now.
On Error GoTo NonEmailError
' Prompt user to fill in subject
If Item.Subject = "" Then
MsgBox "You must enter a subject.", 48, "Empty Subject"
Cancel = True
GoTo NonEmailError
End If
' Exit Sub
' Prompt user to verify E-Mails
If MsgBox(strMsg, vbYesNo + vbQuestion _
, "Send Confirmation") = vbNo Then
Cancel = True
End If
Exit Sub
NonEmailError:
' The item being sent was not an e-mail and so don't prompt the user anything
Exit Sub
End Sub
I am not that familiar with outlook and VBA, but my first guess in this case is that item.class should be compared to the numeric value 43 rather than the string-literal value "43".
The one thing that gives me pause is that I would expect the statement to throw an error because "43" is the wrong type for Item.Class, but this may just reflect my unfamiliarity with the material.
According to msdn reference, item.class (in this case a mailItem) is an OlObjectClass constant, and 43 is olMail. It would probably be advisable to change:
If Item.Class = "43" Then
to
If Item.Class = olMail Then
or at least to:
If Item.Class = 43 Then
( see: http://msdn.microsoft.com/en-us/library/bb208118%28v=office.12%29.aspx and http://msdn.microsoft.com/en-us/library/bb207137%28v=office.12%29.aspx )