VBA outlook call method with On.Action - vba

With a Context Menu option, managed in a class called "Tickets", I want to call a method called "TEmail" defined in the same class that manages the menu event.
I tried to define many different types of .OnAction property using instance, class, name, etc. but without success. I cannot run "TEmail" code.
Public WithEvents AppEvent As Outlook.Application
Private Sub AppEvent_ItemContextMenuDisplay(ByVal CommandBar As Office.CommandBar, ByVal Selection As Selection)
Dim objButton As Office.CommandBarButton
On Error GoTo ErrRoutine
Set objButton = CommandBar.Controls.Add(msoControlButton)
With objButton
.BeginGroup = True
.Caption = "Test-TEmail"
.FaceID = 1000
.Tag = "T-Email"
.OnAction = "TEmail"
End With
EndRoutine:
Exit Sub
ErrRoutine:
MsgBox Err.Number & " - " & Err.Description, vbOKOnly Or vbCritical, "Application_ItemContextMenuDisplay"
GoTo EndRoutine
End Sub
Public Sub TEmail()
... my code ...
End Sub

The solution is to create an event handler.
Public WithEvents AppEvent As Outlook.Application
Public WithEvents myControl As CommandBarButton
Private Sub AppEvent_ItemContextMenuDisplay(ByVal CommandBar As Office.CommandBar, _
ByVal Selection As Selection)
Dim objButton As Office.CommandBarButton
Dim oExp As Outlook.Explorer
Set oExp = Outlook.ActiveExplorer
On Error GoTo ErrRoutine
Set myControl = CommandBar.FindControl(, , "OpenForm")
If myControl Is Nothing Then
Set myControl = CommandBar.Controls.Add(msoControlButton)
With myControl
.Caption = "TEmail"
.FaceID = 59
.Style = msoButtonIconAndCaption
.Tag = "TEmail"
.Visible = True
End With
End If
' ...
End Sub
Private Sub myControl_Click(ByVal Ctrl As Office.CommandBarButton, _
CancelDefault As Boolean)
TEmail
End Sub
Public Sub TEmail()
' ...
End Sub

Related

How to set default selection for listbox in and select an item with key press?

I have a macro in that creates a ListBox.
The first item should be selected as default.
I tried
UserForm.ListBox.Selected(0) = True
I get
How can I control the Listbox from the keyboard? I need to scroll up and down with "UP" and "DOWN" keys and if "ENTER" is pressed the selected Item should be taken.
I tried the following, but this captures every "ENTER" during the code (not only when the UserForm (ListBox) is loaded).
Public Sub Listbox_Enter()
'DO Something
End Sub
Current code:
Option Explicit
Public WithEvents GExplorer As Outlook.Explorer
Public WithEvents GMailItem As Outlook.MailItem
Public WithEvents objInspectors As Outlook.Inspectors
Public WithEvents objTask As Outlook.TaskItem
'Start Outlook
Private Sub Application_Startup()
Set GExplorer = Outlook.Application.ActiveExplorer
Set objInspectors = Outlook.Application.Inspectors
End Sub
'Capture every change, but on same ActiveExplorer (Window)
Private Sub GExplorer_SelectionChange()
Dim xItem As Object
On Error Resume Next
Set xItem = GExplorer.Selection.Item(1)
If xItem.Class <> olMail Then Exit Sub
Set GMailItem = xItem
End Sub
'Reply pressed
Private Sub GMailItem_Reply(ByVal Response As Object, Cancel As Boolean)
AutoAddGreetingtoReply Response
End Sub
'ReplyAll pressed
Private Sub GMailItem_ReplyAll(ByVal Response As Object, Cancel As Boolean)
AutoAddGreetingtoReply Response
End Sub
'Forward pressed
Private Sub GMailItem_Forward(ByVal Response As Object, Cancel As Boolean)
AutoAddGreetingtoReply Response
End Sub
Sub AutoAddGreetingtoReply(Item As Object)
Dim xGreetStr As String: Dim xReplyMail As MailItem
Dim xSenderName As String: Dim lSpace As Long
Dim xRecipient As Recipient: Dim obj As Outlook.MailItem
Dim EmailAdress As String: Dim EmailNameBeforeAtIkon As String:
Dim c As ContactItem
Dim names As String
On Error Resume Next:
Set obj = Outlook.ActiveExplorer.Selection.Item(1)
'This part finds the receipients
If Item.Class <> olMail Then Exit Sub 'Quits if no email is chosen
Set xReplyMail = Item
For Each xRecipient In xReplyMail.Recipients
If xSenderName = "" Then
xSenderName = xRecipient.name
Else
xSenderName = xSenderName & ", " & xRecipient.name
End If
Next xRecipient
Dim lSpace_f As Variant
Dim stFirstNAme As String
Dim st_FirstName As String
Dim currentNAme As String
lSpace_f = InStr(1, xSenderName, " ", vbTextCompare)
If lSpace_f > 0 Then
stFirstNAme = Trim(Split(xSenderName, ",")(1))
st_FirstName = Split(stFirstNAme, " ")(0)
currentNAme = st_FirstName + ","
End If
'Writes a greeting
With UserForm1.Listbox_Auswahl
.AddItem "Hello " + currentNAme
.AddItem "Good morning " + currentNAme
End With
UserForm1.Caption = ("Greeting")
Load UserForm1
UserForm1.StartUpPosition = 2
UserForm1.Show
'Creates the email
With xReplyMail
.Display
.HTMLBody = "<HTML><Body><span style=""color:#0e4a80"">" + markierterEintrag + "</span style=""color:#0e4a80""></HTML></Body>" & .HTMLBody
Sendkeys "{DOWN}", True
Sendkeys "{ENTER}", True
Call Sendkeys("", False)
.Close olSave
End With
End Sub
Public Sub Sendkeys(text As Variant, Optional wait As Boolean = False)
Dim WshShell As Object
Set WshShell = CreateObject("wscript.shell")
WshShell.Sendkeys CStr(text), wait
Set WshShell = Nothing
End Sub
'-------------------------------------
Public Sub Listbox_Auswahl_Click()
If UserForm1.Listbox_Auswahl.ListIndex > -1 Then
markierterEintrag = UserForm1.Listbox_Auswahl.List(UserForm1.Listbox_Auswahl.ListIndex)
End If
Unload UserForm1
End Sub
'Public Sub Listbox_Auswahl_Enter()
' If UserForm1.Listbox_Auswahl.ListIndex > -1 Then
' markierterEintrag = UserForm1.Listbox_Auswahl.List(UserForm1.Listbox_Auswahl.ListIndex)
' End If
'
' Unload UserForm1
'End Sub
This worked for me:
Public Sub Listbox_Auswahl_Click()
If UserForm1.Listbox_Auswahl.ListIndex > -1 Then
markierterEintrag = UserForm1.Listbox_Auswahl.List(UserForm1.Listbox_Auswahl.ListIndex)
End If
End Sub
Public Sub Listbox_Auswahl_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii = 13 Then
With Me.Listbox_Auswahl
If .ListIndex > -1 Then
markierterEintrag = .List(.ListIndex)
End If
End With
Unload UserForm1
End If
End Sub
Public Sub Listbox_Auswahl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If Button = 1 Then
'pressed_key_flag = 1
If UserForm1.Listbox_Auswahl.ListIndex > -1 Then
markierterEintrag = UserForm1.Listbox_Auswahl.List(UserForm1.Listbox_Auswahl.ListIndex)
Unload UserForm1
End If
End If
End Sub

Trigger ItemSend for certain outlook macros only

How would I modify the following code to trigger the event myMailItem_ItemSend only when the email is sent by myMacro1, but not in other cases (such as myMacro2)?
The event should be triggered especially for those macros using the myMailItem object.
Public WithEvents myMailItem As Outlook.MailItem
Public Sub Initialize_handler()
Set myMailItem = Outlook.MailItem
End Sub
Private Sub myMailItem_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, "Send confirmation") = vbNo Then
Cancel = True
End If
End Sub
'Should trigger the send confirmation msgbox
Private Sub myMacro1()
Dim objApp As Outlook.Application
Set objApp = Application
Set myMailItem = objApp.ActiveInspector.CurrentItem.ReplyAll
myMailItem.Display
End Sub
'Should NOT trigger the send confirmation msgbox
Private Sub myMacro2()
Dim objApp As Outlook.Application
Set objApp = Application
Dim oEmail As Outlook.mailItem
Set oEmail = objApp.ActiveInspector.CurrentItem.ReplyAll
oEmail.Display
End Sub
Your kind help would be appreciated.
I would go for this:
Define a global variable in your module, such as Dim TriggerMsgBox As Boolean. By default, the variable will be false.
Initialize it as True in the myMacro1(). Only in that case, it will become True. Else, it will be False.
Use it in the myMailItem_ItemSend event: if the variable is True (meaning we just passed by myMacro1()), then you need to prompt the MsgBox. Else, you will just pass by. Of course, don't forget to reset the variable to False after the MsgBox is hit, else you will keep on showing it even later.
In your code it would be:
Public WithEvents myMailItem As Outlook.MailItem
Dim TriggerMsgBox As Boolean '<-- NEW LINE OF CODE
Public Sub Initialize_handler()
Set myMailItem = Outlook.MailItem
End Sub
Private Sub myMailItem_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim prompt As String
If TriggerMsgBox Then '<-- NEW LINE OF CODE
TriggerMsgBox = False '<-- NEW LINE OF CODE
prompt = "Are you sure you want to send " & Item.Subject & "?"
If MsgBox(prompt, vbYesNo + vbQuestion, "Send confirmation") = vbNo Then
Cancel = True
End If
End If '<-- NEW LINE OF CODE
End Sub
'Should trigger the send confirmation msgbox
Private Sub myMacro1()
Dim objApp As Outlook.Application
Set objApp = Application
Set myMailItem = objApp.ActiveInspector.CurrentItem.ReplyAll
TriggerMsgBox = True '<-- NEW LINE OF CODE
myMailItem.Display
End Sub
'Should NOT trigger the send confirmation msgbox
Private Sub myMacro2()
Dim objApp As Outlook.Application
Set objApp = Application
Dim oEmail As Outlook.mailItem
Set oEmail = objApp.ActiveInspector.CurrentItem.ReplyAll
oEmail.Display
End Sub

How to initialize an event handler

I found this code online. It is supposed to auto populate my subject line with any attachments I provide. The code does not run.
I don't receive an error or anything that suggests its even going through the code.
Public WithEvents olInspectors As Outlook.Inspectors
Public WithEvents olMail As Outlook.MailItem
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Private Sub olInspectors_NewInspector(ByVal Inspector As Inspector)
Dim olItem As Object
Set olItem = Inspector.CurrentItem
If TypeName(olItem) = "MailItem" Then Set olMail = olItem
End Sub
Private Sub olMail_AttachmentAdd(ByVal Attachment As Attachment)
MsgBox "This is a test."
If olMail.Subject = "" Then
'If you don't want the prompt,
'Just delete the Msgbox line and its corresponding "End if".
If MsgBox("Do you want to use the attachment name as the subject", vbYesNo) = vbYes Then
olMail.Subject = Attachment.DisplayName
End If
End If
End Sub
There is nothing wrong with your code, you simply need to Initialize the Inspectors
Click on Sub Initialize_handlers() and press F5
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Or just use Application.Startup Event (Outlook), Save it and restart Outlook then it should work
Example
Public WithEvents olInspectors As Outlook.Inspectors
Public WithEvents olMail As Outlook.mailitem
Private Sub Application_Startup()
Set olInspectors = Application.Inspectors
End Sub
Private Sub Initialize_handlers()
Set olInspectors = Application.Inspectors
End Sub
Private Sub olInspectors_NewInspector(ByVal Inspector As Inspector)
Dim olItem As Object
Set olItem = Inspector.CurrentItem
If TypeName(olItem) = "MailItem" Then Set olMail = olItem
End Sub
Private Sub olMail_AttachmentAdd(ByVal Attachment As Attachment)
MsgBox "This is a test."
If olMail.Subject = "" Then
'If you don't want the prompt,
'Just delete the Msgbox line and its corresponding "End if".
If MsgBox("Do you want to use the attachment name as the subject", _
vbYesNo) = vbYes Then
olMail.Subject = Attachment.DisplayName
End If
End If
End Sub

Run code on Open of an .oft

I want the code below to run on Open of an .oft file/email.
I am getting a Runtime 91 error.
Public WithEvents myItem As Outlook.MailItem
Public EventsDisable As Boolean
Private Sub Application_ItemLoad(ByVal Item As Object)
If EventsDisable = True Then Exit Sub
Set myItem = Item
End Sub
Private Sub myItem_Open(Cancel As Boolean)
EventsDisable = True
Dim Insp As Inspector
Dim obj As Object
Set Insp = Application.ActiveInspector
Set obj = Insp.CurrentItem
obj.HTMLBody = Replace(obj.HTMLBody, "XXXX", Format(Now + 14, "MMMM dd, yyyy"))
Set obj = Nothing
Set Insp = Nothing
EventsDisable = False
End Sub
If I run the last Sub myItem_Open as a public sub manually it works perfectly.
You need to use the Inspectors.NewInspector event instead (Inspectors can be retrieved from Application.Inspectors).
UPDATE. Off the top my head
Public WithEvents myInspectors As Outlook.Inspectors
Private Sub Application_Startup()
set myInspectors = Application.Inspectors
MsgBox "Application_Startup"
End Sub
Private Sub myInspectors_NewInspector(ByVal insp As Inspector)
MsgBox "myInspectors_NewInspector"
Set obj = Insp.CurrentItem
obj.HTMLBody = Replace(obj.HTMLBody, "XXXX", Format(Now + 14, "MMMM dd, yyyy"))
Set obj = Nothing
End Sub

Outlook custom menu buttons

i have 2 menu buttons that i want added in outlook menu after help menu. i made the code to add the buttons but it just adds 2 more buttons every time i reopen outlook even if the 2 menu buttons are there already . Any help is welcomed.
Function ToolBarExists(strName As String) As Boolean
Dim tlbar As commandBar
For Each tlbar In ActiveExplorer.CommandBars
If tlbar.Name = strName Then
ToolBarExists = True
Exit For
End If
Next tlbar
End Function
Sub TBarExistsbutton1()
If ToolBarExists("button1") Then
If ActiveExplorer.CommandBars("button1").Visible = True Then
ActiveExplorer.CommandBars("button1").Visible = False
Else
ActiveExplorer.CommandBars("button1").Visible = True
End If
Else
Call a123
End If
End Sub
Sub TBarExistsbutton2()
If ToolBarExists("button2") Then
If ActiveExplorer.CommandBars("button2").Visible = True Then
ActiveExplorer.CommandBars("button2").Visible = False
Else
ActiveExplorer.CommandBars("button2").Visible = True
End If
Else
Call a1234
End If
End Sub
Sub a123()
Dim outl As Object
Dim msg As Object
Set outl = CreateObject("Outlook.Application")
Dim objBar As Office.commandBar
Dim objButton As Office.commandBarButton
Set objBar = Application.ActiveWindow.CommandBars("Menu Bar")
Set objButton = objBar.Controls.Add(msoControlButton)
With objButton
.caption = "button1"
.onAction = "macro1"
.faceId = 487
.Style = msoButtonIconAndCaption
End With
End Sub
Sub a1234()
Dim outl As Object
Dim msg As Object
Set outl = CreateObject("Outlook.Application")
Dim objBar As Office.commandBar
Dim objButton As Office.commandBarButton
Set objBar = Application.ActiveWindow.CommandBars("Menu Bar")
Set objButton = objBar.Controls.Add(msoControlButton)
With objButton
.caption = "button2"
.onAction = "macro2"
.faceId = 487
.Style = msoButtonIconAndCaption
End With
End Sub
In Outlook 2010. If Visible works for you incorporate it in a similar manner.
Option Explicit
Sub TBarExistsbutton1()
Dim cbControlCount As Long
Dim button1Found As Boolean
Dim j As Long
If ToolBarExists("Menu Bar") Then
cbControlCount = ActiveWindow.CommandBars("Menu Bar").Controls.count
Debug.Print " There are " & cbControlCount & " controls in " & "Menu Bar"
For j = 1 To cbControlCount
Debug.Print ActiveWindow.CommandBars("Menu Bar").Controls(j).Caption
If ActiveWindow.CommandBars("Menu Bar").Controls(j).Caption = "button1" Then
button1Found = True
Exit For
End If
Next j
If button1Found = False Then a123
Else
Debug.Print "Menu Bar does not exist."
a123
End If
End Sub