【发布时间】:2020-05-17 17:26:29
【问题描述】:
在工作表上,我有 3 个 ActiveX 对象,分别是 TextBox1、TextBox2、ListBox1
省略其他代码 我有一个包含
的类 clsEventsPrivate WithEvents txbControl As MSForms.TextBox
Private WithEvents lisControl As MSForms.ListBox
Private txbEvents As TextBoxEvents
Private lisEvents As ListBoxEvents
Private Sub txbControl_Change()
txbEvents.ChangeEvent txbControl
End Sub
Private Sub lisControl_Change()
lisEvents.ChangeEvent lisControl
End Sub
TextBoxEvents 和 ListBoxEvents 类包含
Public Event Changed(txtBox As MSForms.TextBox)
Public Sub ChangeEvent(txtBox As MSForms.TextBox)
RaiseEvent Changed(txtBox)
End Sub
Public Event Changed(ByRef myListBox As MSForms.ListBox)
Public Sub ChangeEvent(lisBox As MSForms.ListBox)
RaiseEvent Changed(lisBox)
End Sub
工作表模块包含
Public WithEvents tbxEvents As TextBoxEvents
Public WithEvents lisEvents As ListBoxEvents
Private Sub tbxEvents_Changed(tbxBox As MSForms.TextBox)
Debug.Print "tbxEvents_Changed " & tbxBox.Name
End Sub
Private Sub lisEvents_Changed(lisBox As MSForms.ListBox)
Debug.Print "lisEvents_Changed " & lisBox.Name
End Sub
Private Sub TextBox2_Change()
Debug.Print "TextBox2_Change"
End Sub
Private Sub TextBox1_Change()
Debug.Print "TextBox1_Change"
End Sub
Private Sub ListBox1_Change()
Debug.Print "ListBox1_Changed "
End Sub
如果我在 TextBox1 或 TextBox2 或 ListBox1 中更改某些内容,调试窗口会显示事件首先将被发送到工作表(TextBox1_Change 等),然后是 tbxEvents_Changed 或 LisEvents_Changed,因此它可以正常工作。
我想要实现的是将 clsEvents 中的代码替换为类似
Private WithEvents objControl As OLEobject
Private txbEvents As TextBoxEvents
Private lisEvents As ListBoxEvents
Private Sub objControl_Change()
if (TypeOf objControl.Object Is MSForms.TextBox) Then
txbEvents.ChangeEvent objControl
elseif (TypeOf objControl.Object Is MSForms.ListBox) Then
lisEvents.ChangeEvent objControl
endif
End Sub
所以基本上我想知道如何实现 WithEvents 的有效定义,这将消除 clsEvents 中“许多”事件函数的必要性。
Public WithEvents objControl As ?????
【问题讨论】:
-
这不是在 VBA 中使用“控件数组”的典型方法 - 您的复杂性更高,并且工作表模块中的每个控件仍然有一个事件处理程序。您是否出于某些特定的设计相关原因而采用这种方法?如果不了解工作表的用例,就很难提出“更好”的方法。
-
在我的应用程序中,我有一个包含大约 40 个 tekstbox、8 个列表框和 48 个标签的工作表,我想根据这些文本和列表框的变化来更改颜色。(我可以根据名称识别标签为每个控件选择)。在其他工作表上,我也确实有许多对象。所以我想要一个事件类来引发所有文本框和列表框的事件。我想让它通用(复选框,选项按钮,...)。通过使用 TextBox 和 ListBox 的基类和 ... 使用 C++ 会很容易,因为它们将具有基类 Control。 .
-
@Tim Williams 当然,我将删除工作表上的 TextBox1_Change (等),它们现在仅用于测试目的,只是为了查看可以在 clsEvents 和其他类中处理哪些事件。我注意到 GotFocus、LostFocus 和 Click 在这些类中无法处理
-
你可以让你所有的 clsEvents 将它们的控制对象传递到一个单独的 sub 中,然后它可以根据控件的名称响应更改事件
-
您可以在 ConnectToConnectionPoint API 的帮助下一次性“捕捉”每个控件的更改事件
标签: excel vba class activex worksheet