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
Related
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
I would like to get the dialog box for a follow-up flag and CategoriesDialog box to set a reminder when I close the mailitem.
I tried to modify the code from here. When I close a mailitem, all things remain normal and I get the category dialog. I can not get the dialog box for follow-up flag like this. There is no error message popup.
Public WithEvents objInspector As Outlook.Inspector
Public WithEvents colInspectors As Outlook.Inspectors
Private Sub Application_Startup()
Init_colInspectorsEvent
End Sub
Private Sub Application_ItemLoad(ByVal Item As Object)
Init_colInspectorsEvent
End Sub
Private Sub Init_colInspectorsEvent()
'Initialize the inspectors events handler
Set colInspectors = Outlook.Inspectors
End Sub
Private Sub colInspectors_NewInspector(ByVal NewInspector As Inspector)
If NewInspector.CurrentItem.Class = olMail Then MsgBox "New mail inspector is opened"
If NewInspector.CurrentItem.Class = olTask Then MsgBox "New Task inspector is opened"
If NewInspector.CurrentItem.Class = olContact Then MsgBox "New Contact inspector is opened"
Set objInspector = NewInspector
End Sub
Private Sub objInspector_Close()
If objInspector.CurrentItem.Class = olMail Then 'MsgBox "Mail inspector is closing"
objInspector.CurrentItem.ShowCategoriesDialog
objInspector.CommandBars.ExecuteMso ("AddReminder") 'No error but not work
objInspector.CurrentItem.Save
End If
End Sub
The Outlook object model doesn't provide any property or method for displaying the Add Reminder... dialog.
The best what you can do is to execute a built-in control programmatically:
CommandBars.ExecuteMso ("AddReminder")
But I don't think the Close event handler is the right place for such things.
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
I'm trying to automatically achieve this workflow:
when user opens a message draft in Outlook (a generated EML file)
if the subject matches a string (immutable, known beforehand, I can't change it; it's something like xyžřy, note the non-ASCII characters):
then add an e-mail to BCC field (immutable, known beforehand, valid e-mail address; let's say it's baz#example.com)
I already know the last part - how to add a BCC to a message, and I use InStr for matching:
Sub addbcc()
Dim objRecip As Recipient
Set oMsg = Application.ActiveInspector.CurrentItem
With oMsg
If InStr(1, oMsg.Subject, "xyžřy") > 0 Then
Set objRecip = oMsg.Recipients.Add("baz#example.com")
objRecip.Type = olBCC
objRecip.Resolve
End If
End With
Set oMsg = Nothing
End Sub
However, the user still needs to remember to press a button to run this macro, which is not more convenient than typing the BCC manually. Is it possible to run the macro automatically when this e-mail is opened?
Is it possible to run the macro automatically when this e-mail is opened?
Work with NewInspector Event , Events occurs when new window is opened by user or through your code.
Example
Option Explicit
Private WithEvents Inspectors As Outlook.Inspectors
Private Sub Application_Startup()
Initialize_handler
End Sub
Public Sub Initialize_handler()
Set Inspectors = Application.Inspectors
End Sub
Private Sub Inspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
If Inspector.currentItem.Class = olMail Then
If Inspector.currentItem.Parent = "Drafts" Then ' Drafts Folder
Debug.Print Inspector.currentItem.Subject ' Immediate Window
' Call Your Code
' Inspector.currentItem.BCC = "baz#example.com"
End If
End If
End Sub
CurrentItem Property
You could monitor the drafts folder with ItemAdd. See the idea here for the inbox. How do I trigger a macro to run after a new mail is received in Outlook?
You could add the bcc in ItemSend. Outlook 2010 - VBA - Set bcc in ItemSend
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.