How to get MediaPlayer_complete event in outlook custom form? - vba

i'm using following code in custom form:
Dim MediaPlayer
Set oMediaPlayer = CreateObject("WMPlayer.OCX.7")
oMediaPlayer.settings.volume = 100
MediaPlayer.controls.stop()
MediaPlayer.settings.autoStart = false
MediaPlayer.URL = strWavFile
MediaPlayer.controls.play()
I would like to know when will be the end of music, like that:
Sub Play_Complete()
MsgBox "Song successfully played"
End Sub
I'm not sure, exist this event in vba-outlook.
I also tried to do time event but when I googled, I did not find anything worthwhile that can apply to my situation. Most of examples didn't work in vba-outlook
Rgds,
Dmitry.

Try to declare the following sub:
Sub oMediaPlayer_Complete()
MsgBox "Song successfully played"
End Sub
where the word after the underscore symbol is the event name.
Anyway, Outlook custom forms is a relatively old technology. Instead, I'd suggest developing an add with an Outlook form region. See Creating Outlook Form Regions for more information.

Related

How to make checkbox control element reference itself [duplicate]

I have a bunch of TextBox-Button pairs on a form. When the button is clicked I want to insert the value of the text box into a database. The name TextBoxes and Buttons follow a naming standard, for example Value1Tb - Value1Cmd and Value2Tb - Value2Cmd.
My problem is that since I want to do the same for every button I would like the possibility to write a Sub like:
Private Sub AnyButton_Click(sender As CommandButton)
Dim tb As TextBox
Set tb = GetTBByName(s.Name)
PutValueToDatabase(s.Name,tb.Text)
End Sub
But I cannot find a way to point the Click-event of a Button to a different sub than the standard Name_Click().
Anybody know a way around this, that doesn't involve me writing 50 or so different Name_Click() subs?
If you are OK to use Form Controls rather that ActiveX, as it looks as though you may be at the moment, then Chris' solution seems good.
However if you need ActiveX CommandButtons then you are unable (as the VBA compiler will tell you, "Procedure declaration does not match...") to have parameters in the callback for the click event, and you are unable to raise the event from multiple objects, although you do of course know which button raised the event (since the relationship is 1 CommandButton = 1 Sub).
So... I would go with something like:
Private Sub Value1Cmd_Click()
Call TheMethod(Value1Cmd)
End Sub
Private Sub Value2Cmd_Click()
Call TheMethod(Value2Cmd)
End Sub
Private Sub TheRealMethod(sender As CommandButton)
' Do your thing '
Dim tb As TextBox
Set tb = GetTBByName(s.Name)
PutValueToDatabase(s.Name,tb.Text)
' Etcetera... '
End Sub
Requires a stub for each button, so some copying and pasting to begin with, but then easy to maintain etcetera as all _Click event callbacks are pointing at the same method...
Edit:
E.g.
Sub AutoWriteTheStubs()
Dim theStubs As String
Dim i As Long
For i = 1 To 10
theStubs = theStubs & "Private Sub Value" & CStr(i) & "Cmd_Click()" & vbCrLf _
& " Call TheMethod(Value" & CStr(i) & "Cmd)" & vbCrLf _
& "End Sub" & vbCrLf & vbCrLf
Next i
Debug.Print theStubs
End Sub
It seems that what you want is to get the name of the clicked button. If you are creating buttons like this:
(where 'i' increments in a loop)
Set btn = Sheet1.Buttons.Add( , , , ,)
With btn
.OnAction = "btnSub"
.Caption = "Upadate"
.Name = "btn" & CStr(i) & "Cmd"
End With
and then defining a generic "private sub btnSub()" for all the buttons, you could at least get the name of the button that was clicked using Application.Caller. Something like:
Private Sub btnSub()
Dim ButtonName As String
ButtonName = Application.Caller
MsgBox ("Hello:" & ButtonName)
End Sub
Hope it helps!
I decided to make this an answer because I am doing something similar and I confirmed that it works.
You can store the OLEobjects in a Collection, of arbitrary size, containing Custom Class Objects that include the OLEobjects and associations and the events that you need. Thus you can completely avoid any code stubs.
Create a Custom Class to bind the Button and TextBox pairs.
Declare the Button object WithEvents.
Include your call-back in the exposed button event handler in the Class Module.
Put a Public routine in a Standard Module to initialise a Collection of these Custom Class objects by spanning the Form Controls. You can also use this to Add the controls programmatically as a 'reBuild' option. The Collection can be inside another Class Module with all of the management routines, but it needs to be Instantiated and loaded in a Standard Module.
Put a public routine in a standard module to receive the call-backs with whatever context you need. This can also be in a Worksheet Module if it makes for better encapsulation. You can use late binding to reference the callback or CallByName.
You need to bear in mind that the Module of the Form will recompile every time you add a control, so you have to be careful where you put your code.
My application has the controls directly on the Worksheet Surface, so I can't put the the Collection Class in, or source any initialisation of the Collection from the Worksheet module. This would amount to self modifying code and it grinds excel to a halt.
I dreamed this idea up through bloody-minded idealism (not necessarily a good thing) but, of course, I was not the first one to think of it as you can see here. #Tim Williams explains it in his answer. You can also google VBA Control Array Events to see plenty of similar examples including an excellent article by #SiddharthRout. In line with the VB6 analogy, he uses an Array instead of a Collection to achieve the same result.
I'll try to post some code later. My application is a bit different so it will take a lot of work to trim it down, but the principle is the same.
The other thing to bear in mind is that VBE really struggles with this type of thing so don't worry if it is loading up you processors. After you re-start with VBE off, all will be fine.
I have this same situation, and I just have a click event for every button that is a wrapper to the function I want to call. This also allows you to pass sheet-specific parameters if you need to.
Example:
Public Sub StoreButton_Click()
' Store values for transaction sheet 3/27/09 ljr
Call StoreTransValues(ActiveSheet)
End Sub
I just published (Open Source) the Event Centralizer for MSForms.
Citation: "The Event Centralizer for MSForms is a VBA programming tool that allows all sorts of custom grouping when writing handlers for the events occurring in UserForms.
With the Event Centralizer for MSForms, it is easy for example to have all TextBoxes react the same way when the Enter event occurs, or all except one, or only those with a particular Tag value.
Thanks to its events logs system, the Event Centralizer for MSForms is a powerful learning and debugging help."
I can't explain here how it works. I tried to do it on the site.
Set the event to =FunctionName(parameter).
A bit late but this may help someone else:
If you have a function called OpenDocumentById(docID as integer), then each control calling the function would have in the event the following:
cmd1's On Click event:
=OpenDocumentById([DocID])
cmd2's On Click event:
=OpenDocumentById([DocID])
etc...

Word Userform Hotkey

I currently use word templates in my business to help create customer mailings. There's a existing userform coding on our templates that insert the proper return address, phone number, legal entity, etc... onto the letter. Lately we've been having issues with a subset of users (seemingly random, we've been through exhaustive testing and cant find rhyme/reason) who do not receive the popup to choose whatever items they need when they enable macros. In testing we've found that the users have been able to go into vbasic and run the userform manually. I'd like to build in a hotkey option to initialize the userform, please help! Currently, the ThisDocument object has this code to run the userform:
Private Sub Document_New()
Channel_Select.Show
End Sub
From what I've been able to find online, something like the OnKey Command from excel could be used, but I cant find the Word version. Does anyone have experience in this?
I found the answer on a thread about keybinding, but I can't refind that thread. I added 2 new modules to my document, module1 has:
Option Explicit
Sub AddKeyBinding()
With Application
' \\ Do customization in THIS document
.CustomizationContext = ThisDocument
' \\ Add keybinding to this document Shorcut: Alt+r
.KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyAlt, wdKeyR), _
KeyCategory:=wdKeyCategoryCommand, _
Command:="TestKeybinding"
End With
End Sub
Module 2
Option Explicit
' \\ Test sub for keybinding
Sub TestKeybinding()
Channel_Select.Show
End Sub
Run the AddKeyBinding macro, then alt+r will launch the userform on the document

Outlook macro icon click event

I have a subroutine assigned to a button on the ribbon. All it does is show a form I'm using to simplify some email processing I need to do. This is a constant work in progress so I added a message box in the form's initialization asking if this is live or not. That changes colors and some functionality to help my testing.
I don't want to have to answer that message box every time I use it (sometimes 30 or 40 times a day) but I still want a clean way to get into my testing mode. I'd like to shift-click or ctrl-click the ribbon icon or something like that to trigger my testing mode.
The public sub is in a module that just shows the form.
Public Sub RunAutoReply()
frmAutoReply.Show
End Sub
Is there any way to do this? I'm on MS Office Pro Plus 2016.
I though I knew what was asked until I read the comments in the question.
This could demo the concept.
Option Explicit
' Choose a name almost impossible to be used elsewhere.
Public testMode_for_RunAutoReply_unique As Boolean
'
Public Sub toggle_testMode_for_RunAutoReply()
testMode_for_RunAutoReply_unique = Not testMode_for_RunAutoReply_unique
If testMode_for_RunAutoReply_unique = True Then
Debug.Print "In test mode"
Else
Debug.Print "In live mode."
End If
End Sub
Public Sub RunAutoReply()
If testMode_for_RunAutoReply_unique = True Then
Debug.Print "Safe to test."
Else
Debug.Print "Live!"
End If
End Sub

using item property inside an event procedure

I have a quick question. How can i check an item's properties within an event procedure? Here is a snippet of what I'm trying to do:
Private Sub application_ItemLoad(ByVal Item As Object)
Dim myolitem As Object
Set myolitem = Item
If myolitem.Class = olMail Then
If myolitem.UnRead Then
UserForm2.Show vbModal
End If
End If
End Sub
Thank you in advance for your help.
You code looks good, I don't see anything strange there.
Hope you will find the Getting Started with VBA in Outlook 2010 article helpful.
Some events (e.g. AfterWrite, ItemLoad) only allow a limited number of properties to be accessed. In your particular case, these are Class and MessageClass - see ApplicationEvents_11_Event.ItemLoad event.
I don't know if MAPIOBJECT is accessible in ItemLoad (I know for sure it is accessible in the AfterWrite event), you can (in theory) access the properties using Extended MAPI (C++ or Delphi) or Redemption (I am its author).

Programming VBA in an Outlook form

I created my own Outlook form to use it as standard surface to enter certain orders instead of the normal message form. The creation, editing and sending works perfectly fine and in the next step I want to insert some code via VBA.
My problem is that I can´t access the objects of my form in the VBA editor. E.g. I want to show a message box when a certain checkbox is checked. According code would be:
Sub example()
If CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
When I run the code I get the error that the object could not be found. The same goes for every other object, like textboxes or labels etc.
I guess the solution is pretty simple, like putting Item. or sth. like that in front of each object. But so far I wasn't able to find the solution.
I´m using Outlook 2010.
I know this is a year too late but you'll want to do something like this example below. It's kinda a work around but you can get whatever value was selected.
Sub ComboBox1_Click()
Set objPage = Item.GetInspector.ModifiedFormPages("Message")
Set Control = objPage.Controls("ComboBox1")
MsgBox "The value in the " & Control.Name & _
"control has changed to " & Control.Value & "."
End Sub
You should be able to get the value, just get a handle on the object you want using the Inspector
The following is an excerpt from here
When you use a custom form, Outlook only supports the Click event for
controls. This is a natural choice for buttons but not optimal for
controls like the combo box. You write the code by inserting it into a
form’s VBScript editor. You need to have the Outlook form open in the
Form Designer and click the View Code button found in the Form group
of the Developer tab.
Sub CheckBox1_Click()
msgbox "Hello World"
End Sub
The code page is fairly minimal with no syntax highlighting. I just tried this now and it does work. Dont forget to Publish your form to pick up the new changes.
I know this is almost 6 years late but, in VB and VBA, simply start with the form name. (And if that doesn't work, just keep going up a parent object and you'll get there.) So, your code becomes:
Sub example()
If MYFORMNAME.CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
Of course, after typing "MYFORMNAME." you'll know if it will work because typomatic will kick in when the system recognizes "MYFORMNAME" after you hit the period.