How to add events to Controls created at runtime in Excel with VBA How to add events to Controls created at runtime in Excel with VBA vba vba

How to add events to Controls created at runtime in Excel with VBA


The code for adding a button at runtime and then to add events is truly as simple as it is difficult to find out. I can say that because I have spent more time on this perplexity and got irritated more than in anything else I ever programmed.

Create a Userform and put in the following code:

Option ExplicitDim ButArray() As New Class2Private Sub UserForm_Initialize()    Dim ctlbut As MSForms.CommandButton        Dim butTop As Long, i As Long    '~~> Decide on the .Top for the 1st TextBox    butTop = 30    For i = 1 To 10        Set ctlbut = Me.Controls.Add("Forms.CommandButton.1", "butTest" & i)        '~~> Define the TextBox .Top and the .Left property here        ctlbut.Top = butTop: ctlbut.Left = 50        ctlbut.Caption = Cells(i, 7).Value        '~~> Increment the .Top for the next TextBox        butTop = butTop + 20        ReDim Preserve ButArray(1 To i)        Set ButArray(i).butEvents = ctlbut    NextEnd Sub

Now you need to add a Class Module to your code for the project. Please remember it's class module; not Module. And put in the following simple code (in my case the class name is Class2).


Public WithEvents butEvents As MSForms.CommandButtonPrivate Sub butEvents_click()    MsgBox "Hi Shrey"End Sub

That's it. Now run it!


Try this:

Sub AddButtonAndShow()    Dim Butn As CommandButton    Dim Line As Long    Dim objForm As Object    Set objForm = ThisWorkbook.VBProject.VBComponents("UserForm1")    Set Butn = objForm.Designer.Controls.Add("Forms.CommandButton.1")    With Butn        .Name = "CommandButton1"        .Caption = "Click me to get the Hello Message"        .Width = 100        .Top = 10    End With    With objForm.CodeModule        Line = .CountOfLines        .InsertLines Line + 1, "Sub CommandButton1_Click()"        .InsertLines Line + 2, "MsgBox ""Hello!"""        .InsertLines Line + 3, "End Sub"    End With    VBA.UserForms.Add(objForm.Name).ShowEnd Sub

This permanently modifies UserForm1 (assuming you save your workbook). If you wanted a temporary userform, then add a new userform instead of setting it to UserForm1. You can then delete the form once you're done with it.

Chip Pearson has some great info about coding the VBE.


DaveShaw, thx for this code man!

I have used it for a togglebutton array (put a 'thumbnail-size' picture called trainer.jpg in the same folder as the excel file for a togglebutton with a picture in it). In the 'click' event the invoker is also available (by the object name as a string)

In the form:

Dim CreateTrainerToggleButtonArray() As New ToggleButtonClass Private Sub CreateTrainerToggleButton(top As Integer, id As Integer)Dim pathToPicture As StringpathToPicture = ThisWorkbook.Path & "\trainer.jpg"Dim idString As StringidString = "TrainerToggleButton" & idDim cCont As MSForms.ToggleButtonSet cCont = Me.Controls.Add _   ("Forms.ToggleButton.1")With cCont   .Name = idString   .Width = 20   .Height = 20   .Left = 6   .top = top   .picture = LoadPicture(pathToPicture)   End With   ReDim Preserve CreateTrainerToggleButtonArray(1 To id)   Set CreateTrainerToggleButtonArray(id).ToggleButtonEvents = cCont   CreateTrainerToggleButtonArray(id).ObjectName = idString   End Sub

and a class "ToggleButtonClass"

  Public WithEvents ToggleButtonEvents As MSForms.ToggleButton  Public ObjectName As String  Private Sub ToggleButtonEvents_click()  MsgBox "DaveShaw is the man... <3 from your friend: " & ObjectName  End Sub

Now just simple call from UserForm_Initialize

 Private Sub UserForm_Initialize()   Dim index As Integer   For index = 1 To 10     Call CreateTrainerToggleButton(100 + (25 * index), index)   Next index End Sub