Vba 在自定义类中调用OnTime方法

Vba 在自定义类中调用OnTime方法,vba,excel,Vba,Excel,我试图在类模块中使用.OnTime方法,但不知道如何在类中调用过程。我看到的所有.OnTime示例都是指从标准代码模块而不是自定义类中使用该方法。是否有任何方法可以调用类模块中的过程而不是标准代码模块 @Alex p:更新为包含代码。以下是课堂模块: Option Explicit Public Sub Test() MsgBox "Success" End Sub Private Sub Class_Initialize() Application.OnTime Ea

我试图在类模块中使用
.OnTime
方法,但不知道如何在类中调用过程。我看到的所有
.OnTime
示例都是指从标准代码模块而不是自定义类中使用该方法。是否有任何方法可以调用类模块中的过程而不是标准代码模块

@Alex p:更新为包含代码。以下是课堂模块:

Option Explicit

Public Sub Test()

    MsgBox "Success"

End Sub

Private Sub Class_Initialize()

    Application.OnTime EarliestTime:=Now + TimeValue("00:00:03"), _
                                    Procedure:="Test"

End Sub
和标准模块:

Option Explicit

Public Sub TestOnTime()

    Dim OnTime As CCOnTime

    Set OnTime = New CCOnTime

End Sub

我还尝试了
过程:=“CClass.Test”

您要求的是magic-VBA是一个全面的工具,但它不是magic

原因是每个类模块只是一个模板,可以在应用程序代码中实例化任意次数。Excel无法正确猜测类模块的哪个特定实例化是调用该方法的正确实例化。您负责做出此决定并管理对适当类实例的引用

啊,你说-但是我想调用的方法没有使用私有数据/引用。这是一种静态方法。答案是VBA不支持类模块上的静态方法,只支持标准模块上的静态方法。任何希望向环境声明为静态的方法都会通过包含在标准模块中而声明为静态


因此,将回调方法放在一个标准模块中,并声明一个私有成员,该成员持有对您希望处理事件的类的特定实例的引用。

您要求的是magic-VBA是一个全面的工具,但它不是magic

原因是每个类模块只是一个模板,可以在应用程序代码中实例化任意次数。Excel无法正确猜测类模块的哪个特定实例化是调用该方法的正确实例化。您负责做出此决定并管理对适当类实例的引用

啊,你说-但是我想调用的方法没有使用私有数据/引用。这是一种静态方法。答案是VBA不支持类模块上的静态方法,只支持标准模块上的静态方法。任何希望向环境声明为静态的方法都会通过包含在标准模块中而声明为静态


因此,将回调方法放在一个标准模块中,并声明一个私有成员,该成员持有对您希望处理事件的类的特定实例的引用。

您要求的是magic-VBA是一个全面的工具,但它不是magic

原因是每个类模块只是一个模板,可以在应用程序代码中实例化任意次数。Excel无法正确猜测类模块的哪个特定实例化是调用该方法的正确实例化。您负责做出此决定并管理对适当类实例的引用

啊,你说-但是我想调用的方法没有使用私有数据/引用。这是一种静态方法。答案是VBA不支持类模块上的静态方法,只支持标准模块上的静态方法。任何希望向环境声明为静态的方法都会通过包含在标准模块中而声明为静态


因此,将回调方法放在一个标准模块中,并声明一个私有成员,该成员持有对您希望处理事件的类的特定实例的引用。

您要求的是magic-VBA是一个全面的工具,但它不是magic

原因是每个类模块只是一个模板,可以在应用程序代码中实例化任意次数。Excel无法正确猜测类模块的哪个特定实例化是调用该方法的正确实例化。您负责做出此决定并管理对适当类实例的引用

啊,你说-但是我想调用的方法没有使用私有数据/引用。这是一种静态方法。答案是VBA不支持类模块上的静态方法,只支持标准模块上的静态方法。任何希望向环境声明为静态的方法都会通过包含在标准模块中而声明为静态


因此,将回调方法放在标准模块中,并声明一个私有成员,该成员持有对要处理事件的类的特定实例的引用。

您可以这样做,但回调需要从标准模块、工作表模块或Thisworkbook返回到对象中

下面是一个在工作表单元格中脉冲输入值的示例。 计时器(几乎)封装在cOnTime类中

主机工作表中实例化了cOnTime对象,其代码模块可以具有设置脉冲时间和回调例程的属性

如果您保护板材,它将开始脉冲,您可以通过取消保护板材来停止脉冲。 如果离开主机工作表,计时器将被终止,如果向后导航,计时器将重新启动(只要工作表受到保护)

类连续时间

Option Explicit
Const DEFPulseTime = "PulseTime"
Const DEFearliestTime As Long = 5
Const DEFlatestTime As Long = 15

Public WithEvents wb As Workbook
Public ws As Worksheet

Private DoWhen As String
Public mPulseTime As Long
Public mNextTime As Double
Property Let callBackDoWhen(cb As String)
    DoWhen = "'" & wb.Name & "'!" & ws.CodeName & "." & cb      'e.g. 'wb Name.xlsm'!Sheet1.kickdog
End Property
Private Function PulseTime() As Long
    On Error Resume Next
         PulseTime = CallByName(ws, DEFPulseTime, VbGet)
         If Err.number <> 0 Then
             PulseTime = DEFearliestTime
         End If
    On Error GoTo 0
End Function
Property Get designMode() As Boolean
    designMode = Not ws.ProtectContents
End Property
Public Sub kickDog()
Const myName As String = "kickDog"
Dim psMessage As String
    If ws Is ActiveSheet And Not designMode Then

        mNextTime = Now + TimeSerial(0, 0, mPulseTime)

        On Error Resume Next
        Application.OnTime mNextTime, DoWhen
        On Error GoTo 0

    End If
    Exit Sub
End Sub
Public Sub killDog()

    If ws Is Nothing Or mNextTime = 0 Then Exit Sub

    On Error Resume Next
    Application.OnTime mNextTime, DoWhen, , False
    On Error GoTo 0

End Sub
Private Sub Class_Initialize()
Dim errorContext As String

    On Error GoTo enableAndExit
        Set wb = ActiveWorkbook
        Set ws = ActiveSheet
    On Error GoTo 0

    callBackDoWhen = DEFDoWhen
    callBackPulseTime = DEFPulseTime
    mPulseTime = PulseTime
    kickDog

    Exit Sub
enableAndExit:
    If Err <> 0 Then
        If ws Is Nothing Then
            errorContext = "ws"
        ElseIf wb Is Nothing Then
            errorContext = "wb"
        End If
    End If
End Sub

Private Sub Class_Terminate()
Const myName As String = "Class_Terminate"

    On Error Resume Next
    killDog
    Set ws = Nothing
    Set wb = Nothing
    Exit Sub

End Sub

Private Sub wb_WindowActivate(ByVal Wn As Window)
    wb_Open
End Sub

Private Sub wb_WindowDeactivate(ByVal Wn As Window)
    killDog
End Sub
Private Sub wb_BeforeClose(Cancel As Boolean)
    killDog
End Sub
Private Sub wb_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    If SaveAsUI Then killDog
End Sub

您可以这样做,但回调需要从标准模块、工作表模块或Thisworkbook返回到对象中

下面是一个在工作表单元格中脉冲输入值的示例。 计时器(几乎)封装在cOnTime类中

主机工作表中实例化了cOnTime对象,其代码模块可以具有设置脉冲时间和回调例程的属性

如果您保护板材,它将开始脉冲,您可以通过取消保护板材来停止脉冲。 如果离开主机工作表,计时器将被终止,如果向后导航,计时器将重新启动
Option Explicit

Const cPulseTime As Long = 1

Dim mOnTime As cOnTime
Property Get PulseTime() As Long
    PulseTime = cPulseTime
End Property
'****************************************
'Timer call-back for cOnTime
Public Sub kickDog()
'   Code to execute on timer event
'******************************************
    On Error Resume Next
    Me.Cells(1, 1) = Not Me.Cells(1, 1)
    On Error GoTo 0
'******************************************
    Debug.Print "woof!!"
    mOnTime.kickDog
End Sub

Private Sub Worksheet_Activate()
    Me.Cells(1,1) = False
    Set mOnTime = New cOnTime
End Sub

Private Sub Worksheet_Deactivate()
    On Error Resume Next
    Set mOnTime = Nothing
End Sub