MailItem.Reply Event not working as expected - vba

I want to write a script that changes the format of the mail, when I am replying to a text- or rtf-mail, using Outlook 2013. To have something to begin with. I used the reply event described in the MS dev centre. Unfortunately the example does not work as I expect it to. For testing, I put in a simple message box that should pop up after clicking the reply button. I never see that message box. What did I do wrong?
Public WithEvents myItem As MailItem
Sub Initialize_Handler()
Set myItem = Application.ActiveInspector.CurrentItem
End Sub
Private Sub myItem_Reply(ByVal Response As Object, Cancel As Boolean)
'Set Response.SaveSentMessageFolder = myItem.Parent
MsgBox "I never see this message box :("
End Sub

Do you click Reply in the Explorer or Inspector? Your code will only run if you click Reply button in an Inspector.

To use the method promoted by Microsoft you need this code in ThisOutlookSession. It would be needed if the event code is not in this special class module.
Private Sub Application_Startup()
Initialize_handler
End Sub
The method described in the answer from Max, where code is in Application_Startup rather than Initialize_handler, can be used if all code is in ThisOutookSession.

you have to put this into "ThisOutlookSession" - only there it will work!
Option Explicit
Private WithEvents objInspectors As Outlook.Inspectors
Private Sub Application_Startup()
Set objInspectors = Outlook.Inspectors
end Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set newItem = Inspector.CurrentItem
End If
Set Inspector = Nothing
End Sub
Public Sub newItem_Open(Cancel As Boolean)
newItem.BodyFormat = olFormatHTML
If newItem.Sent = True Then Exit Sub
End Sub
This will work on any new mail-item, I do not know how to make this work only for replys. You could check the subject, if there is an subject already it will be an reply.

Related

Open “Add reminder” dialog for mail item by Close event

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.

Autofill BCC address

I want to autofill the BCC field with a specific address on replies, forwards and new emails.
I have seen a similar function that performs "silently" - i.e., the BCC address is added once the 'Send' button has been pressed.
I want to be able to remove/change the address if necessary.
From the user's perspective: click reply/forward/new email, and the message window opens up with the BCC field filled.
My knowledge of VBA is somewhat limited, so I'd appreciate if you could be specific about where to place the code.
This code put in ThisOutlookSession module will fire when you click on the button New Email and when replying to an email. From there it's simple to insert whatever you need in the various fields. You need to restart Outlook or manually call Application_Startup() to have it activated the first time.
Option Explicit
Public WithEvents myInspectors As Outlook.Inspectors
Public WithEvents myExplorer As Outlook.Explorer
Private Sub Application_Startup()
Set myInspectors = Application.Inspectors
Set myExplorer = Application.ActiveExplorer
End Sub
Private Sub myInspectors_NewInspector(ByVal Inspector As Inspector)
If TypeName(Inspector.CurrentItem) = "MailItem" Then
'MsgBox "new mail"
Inspector.CurrentItem.BCC = "joe.doe#domain.com"
End If
End Sub
Private Sub myExplorer_InlineResponse(ByVal Item As Object)
'MsgBox "reply"
Item.BCC = "jane.dane#domain.com"
End Sub

Outlook events not firing

I'm trying to send an email based on a calendar reminder going off.
I'm having trouble getting VBA macros to recognize that an Outlook event has occurred.
I put this code in a Class Module:
Public WithEvents myOlApp As Outlook.Application
Sub Initialize_handler()
Set myOlApp = Outlook.Application 'also tried with double quotes around "Outlook.Application"
End Sub
Private Sub myOlApp_Reminder(ByVal Item As Object)
MsgBox ("test")
End Sub
Private Sub myOlApp_NewMail()
MsgBox ("test")
End Sub
When I get a new email or a reminder goes off, nothing happens.
I've tested with this macro in a normal module and it works:
Sub MsgBoxTest()
MsgBox ("test")
End Sub
I have macro settings on "Enable all macros" in the Trust Center.
I've searched google, stackoverflow, a bunch of other websites, and read the documentation on Microsoft.com.
I'm on Outlook 2016 on a PC running Windows 10 Enterprise.
A class module is just a blueprint for an object. A class module doesn't exist all by itself, at runtime a class module is just a type that an object variable can be declared as.
Your code is fine (leaked public field aside).
You're just missing an instance of that class. Keep the class and make ThisOutlookSession create an instance of it:
'[ThisOutlookSession]
Option Explicit
Private AppEvents As AppEventsHandler
Private Sub Application_Startup()
Set AppEvents = New AppEventsHandler
End Sub
Private Sub Application_Quit()
Set AppEvents = Nothing
End Sub
VBA classes fire an Initialize event on creation, and a Terminate event on destruction. Handle them to set your Private WithEvents field:
'[AppEventsHandler] (class module)
Option Explicit
Private WithEvents app As Outlook.Application
Private Sub Class_Initialize()
Set app = Outlook.Application
End Sub
Private Sub Class_Terminate()
Set app = Nothing
End Sub
Private Sub app_NewMail()
'TODO handle app event
End Sub
Private Sub app_Reminder(ByVal Item As Object)
'TODO handle app event
End Sub
'...more handlers...
That's it - now you're handling Outlook.Application events in a dedicated class, without polluting ThisOutlookSession with the nitty-gritty details of every event handler out there.
For this method, often used in documentation, run Initialize_handler manually or run it at startup in the special class module ThisOutlookSession.
Private Sub Application_Startup()
Initialize_handler
End Sub
In order to handle Reminder events, you need to enclose your code in a Sub named "Application_Reminder"
Try this:
Option Explicit
Private Sub Application_Reminder(ByVal Item As Object)
MsgBox "Test"
End Sub

Close event not working when opening and closing multiple Task-items

I got the following situation.
Open an outlook task
The open event is executed
Open a second outlook task
The open event is executed
Close the first task
No close event is executed !!!
Close the second task
The close event is executed
Does anybody have a clue what is happening here ?
Did I do some bad programming ? I have placed my code below.
Thank you in advance.
Kind regards,
Wamor
Public WithEvents objInspectors As Outlook.Inspectors
Public WithEvents objJournal As Outlook.JournalItem
Public WithEvents objTask As Outlook.TaskItem
Dim objOldTask As Outlook.TaskItem
Private Sub Application_Startup()
Set objInspectors = Outlook.Inspectors
Set objTask = Nothing
Set objJournal = Nothing
Set objOldTask = Nothing
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If TypeOf Inspector.CurrentItem Is TaskItem Then
Set objTask = Inspector.CurrentItem
End If
If TypeOf Inspector.CurrentItem Is JournalItem Then
Set objJournal = Inspector.CurrentItem
End If
End Sub
Private Sub objTask_Open(Cancel As Boolean)
MsgBox "TaskItem open event"
End Sub
Private Sub objTask_close(Cancel As Boolean)
MsgBox "TaskItem close event"
End Sub
Of course - you have multiple open objects but only a single variable to store a reference to them.
The standard way of dealing with problems like this is to have a wrapper class that has Inspector and the Item (two items - TaskItem and JournalItem in your case) as variables. TaskOpen and TaskClose event handlers will be methods on that wrapper class.
When NewInspector event fires, create an instance of your wrapper class and populate its properties. Add the wrapper class to a global list.
When close event fires, remove the wrapper class from the list.

Dismiss Outlook reminder

I am having no luck dismissing an Outlook alert programmatically before it displays.
Private Sub Application_Reminder(ByVal Item As Object)
Dim objRem As Reminder
Dim objRems As Reminders
If Item.Subject = "TESTING" Then
'downloadAndSendSpreadReport
Set objRems = Application.Reminders
i = 0
For Each objRem In objRems
i = i + 1
If objRem.Caption = "TESTING" Then
objRems.Remove i
If objRem.IsVisible Then
objRem.Dismiss
End If
Exit For
End If
Next objRem
Item.ReminderSet = False
Item.Delete
'Item.Dismiss
End If
End Sub
I want to use this appointment Item as a trigger to some macro without needing users to manually dismiss the reminder.
Seems to me, when this event is triggered, the reminder item is NOT visible, thus cannot be dismissed
I tried to remove it from the reminders set but this seems to delete the whole event from my calendar. Also, it will still display a STRANGE TITLE reminder not in ASCII.
I tried to set the reminderSet property of the appointment item to false, the reminder property still pops up.
So I am looking for a way to a) dismiss the reminder before it pops automatically/ b). dismiss the reminder after it pops automatically....or any workaround to do a scheduled MACRO in Outlook.
(Please note that I do not have permission to use scheduled job in Windows nor VBS.)
Updates:
Now I have the following code. The reminder is being removed, but it will still pop out a reminder window with a caption like "There is no appointment/reminder" something like this.
The beforeReminderShow event is useful in the sense the Reminder Object isVisible = true
so I can dismiss out.. but the reminders windows will continue to pop up even if there's 0 event.
Private WithEvents olRemind As Outlook.Reminders
Private Sub olRemind_BeforeReminderShow(Cancel As Boolean)
Set objRems = Application.Reminders
For Each objRem In objRems
If objRem.Caption = "TESTING" Then
If objRem.IsVisible Then
objRem.Dismiss
End If
Exit For
End If
Next objRem
End Sub
[Solved] - final edit
The final solution workable (I placed in "ThisOutlookSession" Module).
Hope this helps others.
' declare this object withEvents displaying all the events
Private WithEvents olRemind As Outlook.Reminders
Private Sub Application_Reminder(ByVal Item As Object)
Set olRemind = Outlook.Reminders
' RUN OTHER MACRO HERE
End Sub
Private Sub olRemind_BeforeReminderShow(Cancel As Boolean)
For Each objRem In olRemind
If objRem.Caption = "TESTING" Then
If objRem.IsVisible Then
objRem.Dismiss
Cancel = True
End If
Exit For
End If
Next objRem
End Sub
The only way I know how to do this is as follows.
You need this at the top of your module/class:
Private WithEvents olRemind As Outlook.Reminders
Then when you get your Outlook object you need to do this:
Set olRemind = olApp.Reminders
Where olApp is your Outlook Application object.
Now in your code you need to have this event:
Private Sub olRemind_BeforeReminderShow(Cancel As Boolean)
Once you put the WithEvents at the top then you will be able to see all the events you can use.
Now you can cancel this event and thus not see the reminder window.
If you want to dismiss all the reminders, you can simply implement the following code (declare this object WithEvents displaying all the events):
Private WithEvents olRemind As Outlook.Reminders
Private Sub Application_Reminder(ByVal Item As Object)
Set olRemind = Outlook.Reminders
' RUN OTHER MACRO HERE
End Sub
Private Sub olRemind_BeforeReminderShow(Cancel As Boolean)
Cancel = True
End Sub