【问题标题】:Handling Events for OLEObject CommandButtons created at Runtime处理在运行时创建的 OLEObject 命令按钮的事件
【发布时间】:2023-04-10 20:17:02
【问题描述】:

我已经为这个问题苦苦挣扎了一段时间......我想做一些非常简单的事情。我想在运行时创建多个命令按钮,然后用一个过程处理这些命令按钮的事件。所以我建立了一个“withevents”类来处理自动化,但我的代码不起作用。当我运行 Test() 时,会创建 CommandButton,但是当我单击它时...没有消息框响应...我找不到错误...请任何帮助都很好!!

类 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

【问题讨论】:

  • 我相信工作表控件 (.OLEObjects.Add) 似乎会重新编译项目。如果您愿意,请尝试使用表单控件并为其分配一个.OnClick 事件,或者如果您仍想使用 ActiveX 控件,请尝试此stackoverflow.com/questions/10633387/…

标签: events vba event-handling ole commandbutton


【解决方案1】:

我有一个相当不切实际的解决方案 :-)。要对其进行测试,请将以下代码放入 Sheet1 类模块

对于每个新的 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

【讨论】:

  • 感谢上帝!这个 def 工作......在广泛研究了这个问题之后,不可能使用“withevents”关键字为动态创建的 OLEObjects 构建包装类。唯一的解决方案是以编程方式在 Sheet 模块中为每个创建的对象插入新代码......虽然这不是最优雅的解决方案,但它可以工作。非常感谢丹尼尔!!为了将来参考,您是否认为使用 Visual Studio Tools for Office 更容易实现。我正在考虑熟悉该 API..并现在使用 VSOT 而不是 VBA 形式...
  • 嗨 Sunny,我很高兴它对你有用。除了这个之外,我没有找到工作表上 OLE 按钮的另一种工作解决方案。熟悉 VSTO 非常有用。另一方面,VBA 肯定更容易使用。
猜你喜欢
  • 2020-10-10
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多