Check subject after tabbing to body of mail - vba

Once I tab to the email's body I want to check the subject.
If equal to a specific text then open a template.
I wrote the part about the template.
The difficult part is using the inspectors to check the subject while writing the mail.
Code in thisOutlookSession
Private Sub subject()
Dim subject As String
Dim item As Outlook.MailItem
Dim inspector As Outlook.inspector
Dim template As Outlook.MailItem
Set inspector = Outlook.ActiveInspector
Set item = inspector.CurrentItem
subject = item.subject
Debug.Print subject
If subject = "test" Then
Set template = Application.CreateItemFromTemplate("C:test\test.oft")
Display.template
Else
End If
End Sub

Please, try the next way:
Create three variables on top of ThisOutlookSession:
Private WithEvents m_Inspectors As Outlook.Inspectors
Private WithEvents m_Inspector As Outlook.Inspector
Private WithEvents myItem As Outlook.MailItem
Copy the next Startup event code in ThisOutlookSession module:
Private Sub Application_Startup()
Set m_Inspectors = Application.Inspectors
End Sub
Or copy only the line Set m_Inspectors = Application.Inspectors inside it, if already used for other purposes.
Then, copy the next events code in the same module:
Private Sub m_Inspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
If TypeOf Inspector.CurrentItem Is Outlook.MailItem Then
'Handle emails only:
Set m_Inspector = Inspector
End If
End Sub
Private Sub m_Inspector_Activate()
If TypeOf m_Inspector.CurrentItem Is MailItem Then
Set myItem = m_Inspector.CurrentItem '!!!
End If
End Sub
And the PropertyChange event to be triggered when pressing enter after writing the subject (or clicking somewhere else: body, To, CC etc.):
Private Sub myItem_PropertyChange(ByVal Name As String)
Const specSubject As String = "mySubject..." 'use here the subject you need to open the template!
Const templFullName As String = "C:test\test.oft"
If Name = "Subject" Then
If myItem.Subject = specSubject Then
'do whatever you need...
myItem.Close False 'probably you want closing the new Email. If not, comment this line...
With Application.CreateItemFromTemplate(templFullName)
.Display
End With
End If
End If
End Sub
Now, manually press New Email button and play with the new mail window Subject...

The MailItem exposes aPropertyChange(String Name) event, which fires when the email subject field looses focus (among other).
You can hookup to it, but you need to declare the mail item WithEvents at module level.
See an example below:
Private WithEvents m_item As MailItem
Sub T()
Set m_item = Application.CreateItem(olMailItem)
m_item.Display
End Sub
Private Sub m_item_PropertyChange(ByVal Name As String)
If Name = "Subject" Then Debug.Print m_item.Subject
End Sub

Related

Automatically "Send on Behalf Of" when sent from a specific email account

I could use assistance modifying the Outlook VBA macro. Any time I reply to an e-mail from any of my multiple e-mail accounts the script will change the sender address to the one specified (i.e. user#domain.com on behalf of group#domain.com). I like this behavior but need help making a change so that this script only runs when I am sending from an email address #domain.com. Essentially I would like the macro to have an if statement specifying if sending from an #domain.com email account then run the macro otherwise if sending from another email account i.e. user#gmail.com do not run the macro.
'================================================================================
'Description: Outlook macro to automatically set a different
' From address.
'
'Comment: You can set the email address at the bottom of the code.
' Uncomment the myOlExp_InlineResponse sub to also make it
' work with the Reading Pane reply feature of Outlook 2013/2016/2019/365.
'
' author : Robert Sparnaaij
' version: 1.1
' website: https://www.howto-outlook.com/howto/setfromaddress.htm
'================================================================================
Dim WithEvents objInspectors As Outlook.Inspectors
Dim WithEvents objMailItem As Outlook.MailItem
Dim WithEvents myOlExp As Outlook.Explorer
Private Sub Application_Startup()
Initialize_handler
End Sub
Public Sub Initialize_handler()
Set objInspectors = Application.Inspectors
Set myOlExp = Application.ActiveExplorer
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set objMailItem = Inspector.CurrentItem
If objMailItem.Sent = False Then
Call SetFromAddress(objMailItem)
End If
End If
End Sub
'Uncomment the next 3 lines to enable Outlook 2013/2016/2019/365 Reading Pane Reply
'Private Sub myOlExp_InlineResponse(ByVal objItem As Object)
' Call SetFromAddress(objItem)
'End Sub
Public Sub SetFromAddress(oMail As Outlook.MailItem)
' Set your preferred default From address below.
' Exchange permissions determine if it is actually stamped
' as "Sent On Behalf Of" or "Sent As".
' The address is not properly updated for the InlineResponse
' feature in Outlook 2013/2016/365. This is only a visual bug.
oMail.SentOnBehalfOfName = "delegate#domain.com"
End Sub
Navigate the folder tree up to the email address folder.
This should be objMailItem.Parent.Parent.
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.currentItem.Class = olMail Then
Set objMailItem = Inspector.currentItem
If objMailItem.Sent = False Then
Debug.Print objMailItem.Parent.Parent
If InStr(LCase(objMailItem.Parent.Parent), LCase("#domain.com")) Then
Call SetFromAddress(objMailItem)
End If
End If
End If
End Sub
If you want to handle outgoing emails you need to subscribe to the ItemSend event of the Application class which is fired whenever an Microsoft Outlook item is sent, either by the user through an Inspector (before the inspector is closed, but after the user clicks the Send button) or when the Send method for an Outlook item, such as MailItem, is used in a program.
Public WithEvents myOlApp As Outlook.Application
Public Sub Initialize_handler()
Set myOlApp = Outlook.Application
End Sub
Private Sub myOlApp_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, "Sample") = vbNo Then
Cancel = True
End If
End Sub
In the event handler you may check out the MailItem.SendUsingAccount property which allows setting an Account object that represents the account under which the MailItem is to be sent. The SendUsingAccount property can be used to specify the account that should be used to send the MailItem when the Send method is called.
Depending on the account set on the mail item you may want to set the MailItem.SentOnBehalfOfName property which returns a string indicating the display name for the intended sender of the mail message. You may need to cancel the default action and re-submit the item anew programmatically.
For anyone who finds this.
This should work if you already have the primary account setup in outlook and the account you want to send from has "send on behalf" or "send as" permission:
Dim WithEvents objInspectors As Outlook.Inspectors
Dim WithEvents objMailItem As Outlook.MailItem
Dim WithEvents myOlExp As Outlook.Explorer
Private Sub Application_Startup()
Initialize_handler
End Sub
Public Sub Initialize_handler()
Set objInspectors = Application.Inspectors
Set myOlExp = Application.ActiveExplorer
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set objMailItem = Inspector.CurrentItem
If objMailItem.Sent = False Then
Call SetFromAddress(objMailItem)
End If
End If
End Sub
'Uncomment the next 3 lines to enable Outlook 2013/2016/2019/365 Reading Pane Reply
'Private Sub myOlExp_InlineResponse(ByVal objItem As Object)
'Call SetFromAddress(objItem)
'End Sub
Public Sub SetFromAddress(oMail As Outlook.MailItem)
' Set your preferred default From address below.
' Exchange permissions determine if it is actually stamped
' as "Sent On Behalf Of" or "Sent As".
' The address is not properly updated for the InlineResponse
' feature in Outlook 2013/2016/365. This is only a visual bug.
If oMail.SendUsingAccount = "primary#domain" Then
oMail.SentOnBehalfOfName = "delegate#domain"
End If
End Sub

Auto populate CC field

I am looking for a way that when performing any email action (new email, reply, reply all, forward, etc.) that the CC field gets filled with an email "example#domain.com" before actually sending the email (an Outlook rules adds the CC after sending the email so this does not work)
Reason for adding the CC before the email is sent is so that the user has the ability to remove "examlle#domain.com" if the email is confidential
Any help is greatly appreciated as I have been searching for hours!
I am unsure of your level of VBA experience but here is a question that was asked on Stack Overflow that contains all the basis of what you want to do.
Add CC
The only things to change would be adding the other actions(currently the code use .forward only): New Email, Reply and Reply All.
Be sure to use .Display and not .Send, so that way the email will be displayed and the sender can then edit what he wants before sending the email.
[EDIT]
Option Explicit
Private WithEvents oExpl As Explorer
Private WithEvents oItem As MailItem
Private bDiscardEvents As Boolean
Dim oResponse As MailItem
'to start the macro when outlook starts
Private Sub Application_Startup()
Set oExpl = Application.ActiveExplorer
bDiscardEvents = False
End Sub
Private Sub oExpl_SelectionChange()
On Error Resume Next
Set oItem = oExpl.Selection.Item(1)
End Sub
'on Reply
Private Sub oItem_Reply(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.Reply
afterReply
End Sub
'on Forward
Private Sub oItem_Forward(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.Forward
afterReply
End Sub
'On Reply All
Private Sub oItem_ReplyAll(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.ReplyAll
afterReply
End Sub
Private Sub afterReply()
oResponse.Display
' do whatever here with .to, .cc, .cci, .subject, .HTMLBody, .Attachements.Add, etc.
oResponse.CC = "example#domain.com"
End Sub
Here is the code I put together and tested in my environnement. Just paste it in your VBA editor under ThisOutlookSession. To lauch it click inside the Application_Startup Sub and hit play. It was heavily inspired by another code I found a while back. I do not have the source however. With this everytime you starup Outlook it should start automatically.
#LaZoR_Bear
From some code I found online a while ago to solve this purpose (automatically change the from address on all new emails, replies, reply all, forwards, etc.), I finally figured out the syntax to make it CC on new emails (but your code is still required so thank you again for that).
Code solely to change the from address:
'=================================================================
'Description: Outlook macro to automatically set a different
' From address.
'
'Comment: You can set the email address at the bottom of the code.
' Uncomment the myOlExp_InlineResponse sub to also make it
' work with the Reading Pane reply feature of Outlook 2013/2016/365.
'
' author : Robert Sparnaaij
' version: 1.1
' website: https://www.howto-outlook.com/howto/setfromaddress.htm
'=================================================================
Dim WithEvents objInspectors As Outlook.Inspectors
Dim WithEvents objMailItem As Outlook.MailItem
Dim WithEvents myOlExp As Outlook.Explorer
Private Sub Application_Startup()
Initialize_handler
End Sub
Public Sub Initialize_handler()
Set objInspectors = Application.Inspectors
Set myOlExp = Application.ActiveExplorer
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set objMailItem = Inspector.CurrentItem
If objMailItem.Sent = False Then
Call SetFromAddress(objMailItem)
End If
End If
End Sub
'The next 3 lines to enable Outlook 2013/2016/365 Reading Pane Reply
Private Sub myOlExp_InlineResponse(ByVal objItem As Object)
Call SetFromAddress(objItem)
End Sub
Public Sub SetFromAddress(oMail As Outlook.MailItem)
' Set your preferred default From address below.
' Exchange permissions determine if it is actually stamped
' as "Sent On Behalf Of" or "Sent As".
' The address is not properly updated for the InlineResponse
' feature in Outlook 2013/2016/365. This is only a visual bug.
oMail.SentOnBehalfOfName = "example#doman.com"
End Sub
And then with your code added onto it (plus adding oMail.CC = "example#domain.com" to the code above) looks like this:
Option Explicit
Private WithEvents oExpl As Explorer
Private WithEvents oItem As MailItem
Private bDiscardEvents As Boolean
Dim oResponse As MailItem
Dim WithEvents objInspectors As Outlook.Inspectors
Dim WithEvents objMailItem As Outlook.MailItem
Dim WithEvents myOlExp As Outlook.Explorer
Private Sub Application_Startup()
Initialize_handler
Set oExpl = Application.ActiveExplorer
bDiscardEvents = False
End Sub
Public Sub Initialize_handler()
Set objInspectors = Application.Inspectors
Set myOlExp = Application.ActiveExplorer
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set objMailItem = Inspector.CurrentItem
If objMailItem.Sent = False Then
Call SetFromAddress(objMailItem)
End If
End If
End Sub
'The next 3 lines to enable Outlook 2013/2016/365 Reading Pane Reply
Private Sub myOlExp_InlineResponse(ByVal objItem As Object)
Call SetFromAddress(objItem)
End Sub
Public Sub SetFromAddress(oMail As Outlook.MailItem)
' Set your preferred default From address below.
' Exchange permissions determine if it is actually stamped
' as "Sent On Behalf Of" or "Sent As".
' The address is not properly updated for the InlineResponse
' feature in Outlook 2013/2016/365. This is only a visual bug.
oMail.SentOnBehalfOfName = "example#domain.com"
oMail.CC = "example#domain.com"
End Sub
Private Sub oExpl_SelectionChange()
On Error Resume Next
Set oItem = oExpl.Selection.item(1)
End Sub
'on Reply
Private Sub oItem_Reply(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.Reply
afterReply
End Sub
'on Forward
Private Sub oItem_Forward(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.Forward
afterReply
End Sub
'On Reply All
Private Sub oItem_ReplyAll(ByVal Response As Object, Cancel As Boolean)
Cancel = True
bDiscardEvents = True
Set oResponse = oItem.ReplyAll
afterReply
End Sub
Private Sub afterReply()
oResponse.Display
' do whatever here with .to, .cc, .cci, .subject, .HTMLBody, .Attachements.Add, etc.
oResponse.CC = "example#domain.com"
End Sub

How to popup question, whether to flag, after pressing send button?

Is there a way to ask (popup) if I want to flag the email after I press the send button?
Use the Application.ItemSend event to display a MsgBox asking whether to flag or not.
Then as noted in this question, you'll need to listen to the Items.ItemAdd event on the Sent Items folder and call MarkAsTask on the message passed to the event handler.
So add the following code to ThisOutlookSession - use Alt + F11 to bring up the VB editor.
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim SentItems As Folder
Set SentItems = Outlook.Application.GetNamespace("MAPI").GetDefaultFolder(olFolderSentMail)
Set Items = SentItems.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
Dim property As UserProperty
Set property = Item.UserProperties("FlagForFollowUp")
If property Is Nothing Then Exit Sub
Item.MarkAsTask olMarkThisWeek
Item.Save
End If
End Sub
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
If TypeOf Item Is Outlook.MailItem Then
Dim prompt As String
prompt = "Would you like to flag this item?"
If MsgBox(prompt, vbYesNo + vbQuestion, "Flag item") = vbYes Then
Dim property As UserProperty
Set property = Item.UserProperties.Add("FlagForFollowUp", olYesNo)
property.Value = True
End If
End If
End Sub

Prompt for Subject Line When Creating a New Email

I use 2007 Outlook.
I'm trying to get a code that upon creation of a new email prompts the user to pick one of the fixed radio button options as follows [A]: , [R]:, [F:] , [!]: , Blank (Option to get subject line blank).
I want that selection to be inserted into the subject line automatically.
I found code online but it errors out towards the end of the code.
Private Sub m_colInspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
I pasted this code in the ThisOutlookSession module.
Option Explicit
Private WithEvents m_colInspectors As Outlook.Inspectors
Private WithEvents CurrentInspector As Outlook.Inspector
Private Sub Application_Startup()
Set m_colInspectors = Application.Inspectors
End Sub
Private Sub CurrentInspector_Activate()
Dim oMail As Outlook.MailItem
If Len(UserForm1.SelectedSubject) Then
Set oMail = CurrentInspector.CurrentItem
oMail.Subject = UserForm1.SelectedSubject
End If
Set CurrentInspector = Nothing
End Sub
Private Sub m_colInspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
If TypeOf Inspector.CurrentItem Is Outlook.MailItem Then
If Inspector.CurrentItem.EntryID = vbNullString Then
UserForm1.SelectedSubject = vbNullString
UserForm1.Show
Set CurrentInspector = Inspector
End If
End If
End Sub
I created a form with radio button and a command button where I inserted the following code.
Option Explicit
Public SelectedSubject As String
Private Sub CommandButton1_Click()
If OptionButton1.Value = True Then
SelectedSubject = "Test"
End If
Hide
End Sub
This might get you want you want. Put it under ThisOutlookSession. When the user click on Sends this triggers, meaning they are not able to change the subject line before it is sent. I am using the UserForm1 and the code you are using for that. Add as many radiobuttons as you like and just amend the OptionButton1 to 2 and the value.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim strSubject As String
Dim Prompt$
strSubject = Item.Subject
' Show RadioButtons
UserForm1.Show
' Set Subject Line as the value from the selected RadioButton
strSubject = UserForm1.SelectedSubject
' Set the message subject
Item.Subject = strSubject
strSubject = Item.Subject
' Test if Subject Line is empty
If Len(Trim(strSubject)) = 0 Then
Prompt$ = "Subject is Empty. Are you sure you want to send the Mail?"
If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check for Subject") = vbNo Then
Cancel = True
End If
End If
End Sub

Is there an Outlook event that occurs when a user attaches a document to an email?

I'm working on project to check email attachment size and it notifies the sender when they are trying to attach a large document. I started by using example code shown at http://msdn.microsoft.com/en-us/library/office/aa209975(v=office.11).aspx and it works great as described when running the sub TestAttachAdd(). However, with the code running, when I manually create a new email and attach a file to it, the AttachmentAdd event is not triggered.
Am I using the private sub "newItem_AttachmentAdd" incorrectly for what I'm trying to do?
Or is there another Outlook event that I can use to detect when a user attaches a document (either using the "attach file" ribbon button or by drag-and-drop) to a new email?
Public WithEvents newItem As Outlook.MailItem
Private Sub newItem_AttachmentAdd(ByVal newAttachment As Attachment)
If newAttachment.Type = olByValue Then
newItem.Save
If newItem.Size > 500 Then '500 bytes used for testing purposes only
MsgBox "Warning: Item size is now " & newItem.Size & " bytes."
End If
End If
End Sub
Public Sub TestAttachAdd()
Dim olApp As New Outlook.Application
Dim atts As Outlook.Attachments
Dim newAttachment As Outlook.Attachment
Set newItem = olApp.CreateItem(olMailItem)
newItem.Subject = "Test attachment"
Set atts = newItem.Attachments
Set newAttachment = atts.Add("C:\Test.txt", olByValue)
End Sub
-------------------------- updated with most current working version 1/27/2014
Public WithEvents goInspectors As outlook.Inspectors
Public WithEvents newItem As outlook.MailItem
Private Sub Initialize_Handlers()
Set goInspectors = outlook.Application.Inspectors
End Sub
Private Sub Application_Startup()
Initialize_Handlers
End Sub
Private Sub goInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set newItem = Inspector.CurrentItem
End If
End Sub
Private Sub newItem_AttachmentAdd(ByVal newAttachment As Attachment)
If newAttachment.Type = olByValue Then
newItem.Save
If newItem.Size > 500 Then '500 bytes used for testing purposes only
MsgBox "Warning: Item size is now " & newItem.Size & " bytes."
End If
End If
End Sub
You need to attach your event handler to the right MailItem object.
Trap the Application.Inspectors.NewInspector event, then retrieve the new item from Inspector.CurrentItem.