2013-02-21 125 views
4

我一直在努力解决这个问题,现在...我想做一些非常简单的事情。我想在运行时创建多个commandbutton,然后用一个过程处理这些commandbutton的事件。所以我建立了一个“withevents”类来处理自动化,但是我的代码没有工作。当我运行Test()时,CommandButton被创建,但是当我点击它时...没有消息框响应...我找不到错误..请任何帮助都会很棒!在运行时创建的OLEObject命令按钮的处理事件

类CTEST

Public WithEvents Button As MSForms.CommandButton 

Public Sub Button_Click() 
s = MsgBox("Hello", vbOKOnly) 
End Sub 

模块1

Public TestCollection As Collection 

Sub Test() 

Set TestCollection = New Collection 
Dim Btn As CommandButton 
Dim OLEBtnObj As cTest 
Set OLEBtnObj = New cTest 
Set Btn = Sheet1.OLEObjects.Add(ClassType:="Forms.CommandButton.1", link:=False,_ DisplayAsIcon:=False, Left:=368.25, Top:=51, Width:=44.25, Height:=24).Object 
Set OLEBtnObj.Button = Btn 
TestCollection.Add Item:=OLEBtnObj 

End Sub 
+0

我相信工作表控件(.OLEObjects.Add)似乎重新编译项目。如果你想,尝试使用Form Controls并为其分配一个'.OnClick'事件,或者如果你仍然想使用ActiveX控件,那么试试这个http://stackoverflow.com/questions/10633387/programatically-inserting-click- event-code-for-dynamic-generated-label-not-w – 2013-02-21 07:04:51

回答

5

我有:-)一个而不切实际的解决方案。要测试它,请在Sheet1 Class Module中放置以下代码。

对于每个新的Sheet1按钮,将添加一个新的事件处理。此事件处理程序将执行常见事件处理程序并将单击的命令按钮的名称传递给它。

' Standard Module 
Sub test() 
    ' adds three buttons to Sheet1 with click-event handlers 
    Sheet1.AddButton 
    ActiveCell.Offset(5, 0).Activate 
    Sheet1.AddButton 
    ActiveCell.Offset(5, 0).Activate 
    Sheet1.AddButton 
End Sub 

' Sheet1 Class Module 
Option Explicit 

' Add Microsoft Visual Basic For Applications Extensibility 

Public Function AddButton() As MSForms.CommandButton 
    Dim msFormsCommandButton As MSForms.CommandButton 
    Set msFormsCommandButton = Me.OLEObjects.Add(ClassType:="Forms.CommandButton.1").Object 
    CreateEventHandler msFormsCommandButton.Name 
    Set AddButton = msFormsCommandButton 
End Function 

Private Sub CommonButton_Click(ByVal buttonName As String) 
    MsgBox "You clicked button [" & buttonName & "]" 
End Sub 

Private Sub CreateEventHandler(ByVal buttonName As String) 
    Dim VBComp As VBIDE.VBComponent 
    Dim CodeMod As VBIDE.CodeModule 
    Dim codeText As String 
    Dim LineNum As Long 

    Set VBComp = ThisWorkbook.VBProject.VBComponents(Me.CodeName) 
    Set CodeMod = VBComp.CodeModule 
    LineNum = CodeMod.CountOfLines + 1 

    codeText = codeText & "Private Sub " & buttonName & "_Click()" & vbCrLf 
    codeText = codeText & " Dim buttonName As String" & vbCrLf 
    codeText = codeText & " buttonName = """ & buttonName & "" & vbCrLf 
    codeText = codeText & " CommonButton_Click buttonName" & vbCrLf 
    codeText = codeText & "End Sub" 
    CodeMod.InsertLines LineNum, codeText 
End Sub 
+0

感谢上帝!这个def的工作原理......在广泛研究这个问题之后,我们无法使用“withevents”关键字为动态创建的OLEObjects构建包装类。唯一的解决方案是以编程方式为每个创建的对象在工作表模块中插入新代码...虽然这不是最优雅的解决方案,但它工作正常。非常感谢丹尼尔!并且为了将来的参考,您是否认为使用Visual Studio Tools for Office实现起来要容易得多。我想要熟悉那个API。现在使用VSOT而不是VBA形式... – 2013-02-21 22:44:13

+1

嗨,Sunny,我很高兴它对你有用。除此之外,我没有找到其他工作表上OLE按钮的解决方案。熟悉VSTO非常有用。另一方面,VBA非常容易处理。 – dee 2013-02-22 07:10:35