【问题标题】:Click Event in Class Module Not Firing 2.0类模块中的单击事件未触发 2.0
【发布时间】:2018-01-10 11:44:17
【问题描述】:

我有一个类似的问题,如以下链接所述:Click Event in Class Module Not Firing

(没有代表在那里发表评论并要求澄清,所以提出了一个新问题)

我的设置如下:

Userform_Initialize 调用为该用户窗体创建组合框的模块中的子,这些组合框被设置为类模块。

如果我正确理解链接中给出的答案,则在显示用户表单之前会忘记 ComboBox 和 Class Module 之间的连接,因此不会触发该操作。不幸的是,我无法让它工作。

我想知道是否有人可以指定链接中给出的答案。我应该把“Option Explicit”和“Private clsLabel As UserFormLabelLink”放在哪里?我尝试了几个位置,但每次都收到不同的错误(编译错误)。

(当我将 UserForm.Show 放入创建这些 ComboBox 的模块中时,该操作会触发,但这会在 Userform 的后期阶段创建一个 91 错误。)

如果有人可以提供帮助,将不胜感激!

编辑 - 这是代码

模块

Dim inputComboH As cComboHandler
Set collInputCombo = New Collection
Dim userformCombo As ComboBox

Set userformCombo = UserForm1.MultiPage1.Page1.Controls("Frame1").Add("Forms.ComboBox.1")
            With userformCombo
                .Name = "ComboBox"
                'Add items to the combobox
                For k = 0 To 5
                    .AddItem "Item" & k
                Next k


                    Set inputComboH = New cComboHandler
                    Set inputComboH.inputComboH = userformCombo
                    collInputCombo.Add inputComboH


            End With

类模块 cComboHandler

Public WithEvents inputComboH As MSForms.ComboBox
Public Sub inputComboH_Click()
    MsgBox "Clicked"
End Sub

【问题讨论】:

  • 如果您发布代码会很有帮助。请查看How to Ask
  • 嗨 Aron,制作和编辑

标签: vba class module


【解决方案1】:

Option Explicit 应该放在每个模块/类的顶部。它可以防止您使用未声明的变量。没有Option Explicit,此代码有效。

Sub Example1()

    ' Ctrl + G will open the immediate window, if closed.
    ' You'll need this to view the output.
    myMessage = "Hello World"
    Debug.Print myMessage
End Sub

虽然您从未明确声明 myMessage,但它是为您创建的。

添加Option Explicit 可防止运行相同的代码。你会得到一个错误:

编译错误:

变量未定义

Option Explicit

Sub Example1()

    ' To fix add "Dim myMessage As String" above this line.
    ' The next line is responsible for the error.
    myMessage = "Hello World"
    Debug.Print myMessage
End Sub

这可以帮助您避免细微的错误。在此示例中,如果没有显式选项,拼写错误会创建两个变量。

' myCounter and myCount are meant to be the same
' variable.  The user forgot/mistyped the name the
' second time around, leading to an infinite loop.
'
' You can run this code.
' Press Cntrl + Break to pause/reset to stop.
Sub Exmaple2()

    myCounter = 1
    Do
        Debug.Print myCounter
        myCount = myCount + 1    ' This line contains our "error"
        DoEvents
    Loop Until myCounter = 100
End Sub

您可以从选项菜单(工具 >> 选项 >> 要求变量声明)自动为每个模块添加显式选项(这是一个好主意)。

您的第二个问题是关于scope。范围控制如何访问变量,以及它们的寿命。当一个变量不再是访问它的有效方式时,它就会离开作用域。此时,变量被销毁(这在技术上可能并不总是正确的,但出于实际目的,这是可以的)。

在子/函数中声明的变量具有局部作用域。这意味着它们只能在声明过程中访问。当程序结束时,它们不能再被访问,因此被销毁。一旦销毁,它们持有的任何值都会丢失(这就是您的事件不会触发的原因 - 包含事件的对象会丢失)。

' At the end of this sub, i will always equal 1,
' regardless of the number of times you execute it.
' This is because i is created each time you call the sub, and destroyed when it ends.
' Each new verson of i has a default value of 0, to which we add one.
Sub Example2()

    Dim i As Integer
    i = i + 1
    Debug.Print i
End Sub

现在让我们在模块/类级别声明i。在模块作用域中,变量将一直存在,直到整个模块离开作用域。这将在以下情况下发生:

  • 用户按下复位键。
  • 遇到End 命令。
  • 父工作簿已关闭。
  • 在类的情况下;课程离开了范围。

例子:

' i is declared at the module/class level.
' It's value is maintained between calls to Example3.
Private i As Integer

' Each call to this sub will increment i by 1.
' Call 1 will output 1.
' Call 2 will output 2.
' etc
Sub Example3()

    i = i + 1
    Debug.Print i
End Sub

范围是一个很大的话题,一开始可能会令人困惑。大多数VBA books 都覆盖了这个。

【讨论】:

  • 感谢您的回答@destination-data 非常感谢
  • 您能否进一步详细说明我的数据?我假设我应该增加 inputComboH 的范围,但是我在哪里做呢?再次, Userform_initialize 调用分配类模块的模块。我是否也应该更改 Sub 的范围?
  • 因为collInputCombo 包含您所有的inputComboH 类,所以保持在范围内很重要。 VBA 摧毁它的那一刻,你将失去你的课程,以及他们的事件。在任何 subs/func 之外声明 collInputCombo。示例:Private collInputCombo As Collection。假设这是在一个模块内。如果在一个类中,它可能会更复杂。
猜你喜欢
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多