Назначение функции VBA при щелчке динамически создаваемой кнопки в форме пользователя Excel

Я создаю кнопки динамически на пользовательской форме Excel со следующим кодом:

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

Я хотел бы назначить функцию для запуска при нажатии этих кнопок, но я не могу найти простой способ сделать это, так как нет свойства как часть самой кнопки.

есть ли способ сделать это, используя вышеуказанную идиому? Должен ли я действовать по-другому?

5 ответов


нужно динамически создавать код обработчиков событий для каждой кнопки.

Это займет немного времени-смотрите здесь:http://navpadexcel.blogspot.com/2006/11/httpwwwcpearsoncomexcelvbehtm.html

лучший способ-создать кучу кнопок на форме (столько, сколько вам понадобится) раньше времени. Также создайте код обработчика событий. Сделайте их все скрытыми изначально.

затем, когда ваша форма откроется, вы можете динамически изменить надписи на кнопках, сделайте их видимыми и переместите их. Первоначально созданный код события будет связан с активированными кнопками, как и ожидалось.


чтобы добавить событие управления динамически в форме Excel; необходимо сначала добавить событие(ы) в модуле класса. Например, я собираюсь добавить модуль класса clsTEST с одним событием 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

Как вы можете видеть, единственное, что это сделает, это установить заголовок на кнопке, а затем количество раз, когда вы нажали его. Далее в коде формы введите следующее:

    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

когда вы активируете форму, она создаст кнопку. каждый раз, когда вы нажимаете на кнопке заголовок изменится.


ниже код должен работать

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

Я тоже смотрел на это. Кажется, вы можете запустить макрос, используя свойство onClick:

Command1.OnClick = "Macro1"

затем создайте макрос с этим именем, который запускает нужную функцию. Это мой Хак вокруг этого, пока я не найду что-то лучше.