Question

I'm creating buttons dynamically on an Excel userform with the following code:

With Me.CurrentFrame.Controls.Add("Forms.CommandButton.1")
    .Caption = "XYZ"
    .name = "AButton"
    .Font.Bold = True
    .ForeColor = &HFF&
    ... blah blah blah
End With

I'd like to assign a function to run when these buttons are clicked, but I can't find a straightforward way to do this since there's no property as part of the button itself.

Is there a way to do this using the above idiom? Should I be going about this whole thing in a different way?

Was it helpful?

Solution

You need to dynamically create code / event handlers for each button.

It take a bit of doing - see here: http://navpadexcel.blogspot.com/2006/11/httpwwwcpearsoncomexcelvbehtm.html

A better way might be to create a bunch of buttons on the form (as many as you think you'll need) ahead of time. Create the event handler code as well. Make them all hidden initially.

Then when your form opens you can dynamically change the button captions, make them visible and move them around. The event code you created initially will be linked to the activated buttons as expected.

OTHER TIPS

To add a control event dynamically in an Excel form; you need to first add the event(s) in a class module. For my example, I am going to add a class module named clsTEST with one event, btn_click()

    '#### CLASS NAMED clsTEST
    Public WithEvents btn As MSForms.CommandButton
    Public frm As UserForm

    Dim iCount As Long

    Private Sub btn_Click()

    iCount = IIf(iCount < 1, 1, iCount + 1)
    btn.Caption = "Count " & Str(iCount)

End Sub
'### END CLASS

As you can see, the only thing this will do is set the caption on the button to then number of times you clicked it. Next, in the form code enter the following:

    Dim mColButtons As New Collection    '## SET A NEW COLLECTION

    Private Sub UserForm_Activate()
    '
    Dim btnEvent As clsTEST
    Dim ctl As MSForms.Control
    '
    Set ctl = Me.Controls.Add("Forms.CommandButton.1")
    '
    With ctl
    .Caption = "XYZ"
    .Name = "AButton"
    END With
    '
    Set btnEvent = new clsTEST   
    Set btnEvent.btn = ctl
    set btnEvent.frm = Me
    '
    mColButtons.add btnEvent
    'End Sub

When you activate the form, it will create a button. every time you click on the button the caption will change.

The below code should be working

Dim NewButton As OLEObject
Dim CodeModule As Object

Set NewButton = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", _
    Link:=False, DisplayAsIcon:=False, Left:=52.5, Top:=Hght, _
    Width:=202.5, Height:=26.25)
NewButton.Object.Caption = "Click Me!"
Set CodeModule = ActiveWorkbook.VBProject.VBComponents.VBE.ActiveCodePane.CodeModule
CodeModule.InsertLines CodeModule.CreateEventProc("Click", NewButton.Name) + 1, vbTab & "MsgBox ""Hello world"""
Sub Oval1_Click()
    file = ActiveWorkbook.Name
    Set Output = Workbooks.Add()
    ActiveWorkbook.SaveAs Filename:="Try.xls"        
    Sheets(1).Select        
    ActiveSheet.Buttons.Add(460, 10, 140, 30).Select
    ActiveSheet.Buttons.Text = "DATA"      
    ActiveSheet.Shapes("Button 1").Select
    Selection.OnAction = "Book1.xlsm!data_Click"
End Sub

Sub data_Click()      
    MsgBox "you have clicked me"       
    ActiveSheet.DrawingObjects.Delete        
End Sub

I've been looking at this as well. Seems you can run a macro by using the onClick property:

Command1.OnClick = "Macro1"

Then create a macro by that name that runs the desired function. This is my hack around this until I find something better.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top