How to capture click event from macro created control?

donwiss

Board Regular
Joined
Jul 5, 2020
Messages
63
Platform
  1. Windows
One can dynamically add controls to a UserForm. Like CheckBoxes and OptionButtons. See
Add method (Microsoft Forms)

But how can I capture a click event on these controls? If I could capture a general click, then maybe something like Application.Caller will tell me which was clicked.
 

Excel Facts

Move date out one month or year
Use =EDATE(A2,1) for one month later. Use EDATE(A2,12) for one year later.
Something along these lines. This is a most basic example. If it's not comprehensive enough to solve your problem, there are more thorough approaches. Post more about your project if necessary such as what type of controls are being added and how you will respond to events as a group and individually.

 
Upvote 0
There are no WorkSheets in this. All VBA and UserForms. I'm putting on the forms both CheckBoxes and OptionButtons.
 
Upvote 0
You can use this as a template more or less.

Add a userform and this code:
VBA Code:
Option Explicit

Private MyCommonClickReferences As New Collection

Private Sub UserForm_Initialize()
    AddControls
End Sub

Private Sub AddControls()

    Dim t As Single, cb As MSForms.CheckBox, ob As MSForms.OptionButton, cc As CommonClick
    
    For t = 20 To 220 Step 20
        
        Set cb = UserForm1.Controls.Add("Forms.CheckBox.1", "CheckBox" & t / 20)
        cb.Move 10, t
        cb.Caption = "Check Box " & t / 20
        Set cc = New CommonClick
        cc.Init cb
        MyCommonClickReferences.Add cc

        Set ob = UserForm1.Controls.Add("Forms.OptionButton.1", "OptionButton" & t / 20)
        ob.Move 100, t
        ob.Caption = "Option Button " & t / 20
        Set cc = New CommonClick
        cc.Init ob
        MyCommonClickReferences.Add cc
    
    Next
    
    Me.Move Left, Top, ob.Left + ob.Width, ob.Top + ob.Height + 40

End Sub

Public Sub CommonClick(c As MSForms.Control)
    MsgBox "Type: " & TypeName(c) & vbCrLf & "Name: " & c.Name & vbCrLf & "Caption: " & c.Caption
End Sub


Create a class named CommonClick. Add the following:
VBA Code:
Option Explicit

Private WithEvents OptionButton As MSForms.OptionButton
Private WithEvents CheckBox As MSForms.CheckBox

Private Parent As Object

Friend Sub Init(c As MSForms.Control)

    Select Case TypeName(c)
        
        Case "OptionButton"
        
            Set OptionButton = c
        
        Case "CheckBox"
        
            Set CheckBox = c
        
    End Select
    
    Set Parent = c.Parent
        
End Sub

Private Sub OptionButton_Click()
    Parent.CommonClick OptionButton
End Sub

Private Sub CheckBox_Click()
    Parent.CommonClick CheckBox
End Sub

Open the userform.
Example file available in this folder. See: Dynamic Controls Conmmon Events with CallBack.xlsm
 
Upvote 0
Solution
Works like a charm. I implemented it for OptionButtons, which is where it is really useful. Before the user had to make the selection, then press a button. The macro looped to find the one True. That button is now gone. Make the selection, and it is made, and the form closes.

There are a few places where I dynamically put the controls onto the form. In this case, it is a form that lets the user change the Default Printer. During form initialization, the macro gets the available list. And the form is sized for the list.

Because clicking the OptionButton is setting the printer, there is a delay before the form closes. So I put a setting printer message in the StatusBar.

Thank you very much for this.
 
Upvote 0
I noticed a difference between this and clicking on a non-dynamic OptionButton with similar code behind. In the dynamic one, the button turns True, and then the form closes. In the non-dynamic, the button background turns gray, and then the form closes.

I was thinking of implementing this only for OptionButtons. It would seem then that the Class Module could be greatly simplified.
 
Upvote 0
I was thinking of implementing this only for OptionButtons. It would seem then that the Class Module could be greatly simplified.

Agree. Typically, that is what I would do. Create a different class for each type of control. It could get cluttered pretty quickly if you begin having different requirements for different controls.

I noticed a difference between this and clicking on a non-dynamic OptionButton with similar code behind. In the dynamic one, the button turns True, and then the form closes. In the non-dynamic, the button background turns gray, and then the form closes.

There may be different default properties for design time controls as opposed to dynamic ones. I don't know.
 
Upvote 0
@dataluver
Could you please post the OptionButton only Class Module. I know nothing about Class Modules. Having both the single, and the double to compare, will give us an example of going from one to two.

The dynamic CheckBoxes are a list of Access Tables that are lockable, holding the state of whether locking is turned on or not. What I'm doing is when the close button is pressed, it compares the state of each button with the state it was when initialized. Changing just the ones needed in batch is more efficient than changing when each is clicked.
 
Upvote 0
I suppose that this is all you will need?

VBA Code:
Option Explicit

Private WithEvents OptionButton As MSForms.OptionButton

Private Parent As Object

Friend Sub Init(c As MSForms.OptionButton)
    Set OptionButton = c
    Set Parent = c.Parent
End Sub

Private Sub OptionButton_Click()
    Parent.CommonClick OptionButton
End Sub
 
Upvote 0
Yes. I see we still have a Parent and Friend, a concept I've not seen before.
Thank you for the additional code.
 
Upvote 0

Forum statistics

Threads
1,214,639
Messages
6,120,679
Members
448,977
Latest member
dbonilla0331

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top