如何将事件添加到使用VBA在Excel中运行时创build的控件

我想在Excel中使用VBA在运行时添加一个控件和相关的事件,但我不知道如何添加事件。

我尝试了下面的代码,并且在我的用户窗体中正确创build了button,但是应该显示hello消息的关联的单击事件不起作用。

任何build议/更正将受到欢迎。

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

在运行时添加一个button,然后添加事件的代码真的很简单,因为很难找出…我可以这样说,因为我已经花了更多的时间在这个困惑和恼火比我在任何其他编程

创build一个用户窗体,并input以下代码:

 Option Explicit Dim ButArray() As New Class2 Private 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 Next End Sub 

现在你需要添加一个类模块到你的代码的项目..请记住它的类模块不Module.And放在以下简单的代码(在我的情况下,类名是Class2)


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

而已。 现在运行它

DaveShaw,这个代码人的thx!

我用它作为一个togglebutton数组(把一个名为trainer.jpg的缩略图大小的图片放在一个带有图片的togglebutton的excel文件所在的文件夹中)。 在“click”事件中,调用者也是可用的(通过对象名称作为string)

forms如下:

 Dim CreateTrainerToggleButtonArray() As New ToggleButtonClass Private Sub CreateTrainerToggleButton(top As Integer, id As Integer) Dim pathToPicture As String pathToPicture = ThisWorkbook.Path & "\trainer.jpg" Dim idString As String idString = "TrainerToggleButton" & id Dim cCont As MSForms.ToggleButton Set 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 

和一个类“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 

现在只需从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 

尝试这个:

 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).Show End Sub 

这永久修改UserForm1(假设您保存您的工作簿)。 如果你想要一个临时的用户窗体,然后添加一个新的用户窗体,而不是将其设置为UserForm1。 然后,您可以在完成后删除表单。

Chip Pearson有关于编码VBE的一些很好的信息。

这是我的解决scheme添加一个commandbutton和代码,而不使用类它添加了一个引用,允许访问vbide添加button

然后编写一个函数来处理工作表中的click事件

 Sub AddButton() Call addref Set rng = DestSh.Range("B" & x + 3) 'Set btn = DestSh.Buttons.Add(rng.Left, rng.Top, rng.Width, rng.Height) Set myButton = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1", Left:=rng.Left, Top:=rng.Top, Height:=rng.Height * 3, Width:=rng.Width * 3) DoEvents With myButton '.Placement = XlPlacement.xlFreeFloating .Object.Caption = "Export" .Name = "BtnExport" .Object.PicturePosition = 1 .Object.Font.Size = 14 End With Stop myButton.Object.Picture = LoadPicture("F:\Finalised reports\Templates\Macros\evolution48.bmp") Call CreateButtonEvent End Sub Sub addref() On Error Resume Next Application.VBE.ActiveVBProject.References.AddFromFile "C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" Application.VBE.ActiveVBProject.References.AddFromFile "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" End Sub Private Sub CreateButtonEvent() On Error GoTo errtrap Dim oXl As Application: Set oXl = Application oXl.EnableEvents = False oXl.DisplayAlerts = False oXl.ScreenUpdating = False oXl.VBE.MainWindow.Visible = False Dim oWs As Worksheet Dim oVBproj As VBIDE.VBProject Dim oVBcomp As VBIDE.VBComponent Dim oVBmod As VBIDE.CodeModule ' Dim lLine As Single Const QUOTE As String = """" Set oWs = Sheets("Contingency") Set oVBproj = ThisWorkbook.VBProject Set oVBcomp = oVBproj.VBComponents(oWs.CodeName) Set oVBmod = oVBcomp.CodeModule With oVBmod lLine = .CreateEventProc("Click", "BtnExport") + 1 .InsertLines lLine, "Call CSVFile" End With oXl.EnableEvents = True oXl.DisplayAlerts = True Exit Sub errtrap: End Sub 

我认为代码需要被添加到用户窗体,而不是button本身。

所以像

 With UserForm1.CodeModule 'Insert code here End With 

代替你的With ThisWorkbook