2009-02-19 31 views
8

estoy creando botones de forma dinámica en un UserForm Excel con el siguiente código:Assign en función de VBA clic a un botón creado de forma dinámica en Excel formUsuario

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

me gustaría asignar una función a ejecutar cuando Se hace clic en estos botones, pero no puedo encontrar una forma directa de hacerlo, ya que no hay ninguna propiedad como parte del botón.

¿Hay alguna manera de hacer esto usando la expresión anterior? ¿Debería hacer todo esto de otra manera?

Respuesta

8

Necesita crear dinámicamente controladores de código/evento para cada botón.

se tarda un poco de hacer - ver aquí: http://navpadexcel.blogspot.com/2006/11/httpwwwcpearsoncomexcelvbehtm.html

Una mejor manera podría ser la creación de un grupo de botones de la forma (todas las que cree que necesitará) antes de tiempo. Crea el código del controlador de eventos también. Hazlos todos ocultos inicialmente.

Luego, cuando se abre su formulario, puede cambiar dinámicamente los títulos de los botones, hacerlos visibles y moverlos. El código de evento que creó inicialmente se vinculará a los botones activados como se esperaba.

+2

idea inteligente! Parece que todo en VBA requiere ser inteligente. – notnot

0

He estado mirando esto también. Parece que se puede ejecutar una macro utilizando la propiedad onClick:

Command1.OnClick = "Macro1" 

A continuación, cree una macro con ese nombre que se ejecuta la función deseada. Este es mi hack alrededor de esto hasta que encuentre algo mejor.

+0

Para un control de forma de usuario de Excel, el mensaje "onClick" resultó en ... "El objeto no admite esta propiedad o método" – PravyNandas

2

El siguiente código debería estar trabajando

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""" 
1
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 
+0

Me refiero a botones agregados a formas de usuario, no a la hoja de trabajo – notnot

13

Para añadir un evento de control de forma dinámica en una forma de Excel; primero debe agregar el evento (s) en un módulo de clase. Para mi ejemplo, voy a agregar un módulo de clase denominado clsTest con un evento, 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 

Como se puede ver, la única cosa que esto hará es establecer el título en el botón a continuación, el número de veces que hizo clic. A continuación, en el código del formulario introduzca lo siguiente:

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 

Cuando se activa la forma, se creará un botón. cada vez que haga clic en el botón, la leyenda cambiará.

+0

Esto funcionó muy bien para mí. Me preguntaba si hay alguna manera de enviar una variable a la clase. Por ejemplo, si tuviera que cambiar .caption a lo que envíe. Private Sub btn_Click (Q1 como secuencia) He intentado esto, pero dio lugar a "Objeto no admite esta propiedad o método" – JahKnows

+0

Eso es correcto. Los eventos _Click() no aceptan ningún parámetro. Lo que alternativamente puede intentar es establecer otra variable privada dentro de la clase y asignarle subtítulos primero, y luego configurar su evento para el controlador. – PravyNandas

Cuestiones relacionadas