宏重叠自己

时间:2017-01-07 18:06:38

标签: excel vba excel-vba macros

我正在写一个VBA代码,通知我什么时候离开办公室。 它有时间从工作簿表中提示我,但是当我更新我上班的时间,午餐时间等等时,价值会发生变化。 我创建了一个在某些单元格发生变化时触发的代码,问题是单元格在到达实际应该离开的时间之前会多次更改。所以我没有得到一个通知,而是获得了多个通知。 基本上相同的宏运行多次。当我更改一个单元格时,如果它正在运行,它应该实际上停止它,并重新启动我的宏。有可能吗? 我用谷歌搜索了它并没有什么帮助。

Sub NotifyMe()
'Declare Variables
    Dim notificationStr, leaveStr As String
    Dim notificationTime As Date
    Dim leaveTime As Date

'Defines now Time
    h = Hour(Now())
    m = Minute(Now())
    s = Second(Now())
    nowtime = TimeSerial(h, m, s)
'Defines the time it will prompt me
    leaveTime = Cells(5, 2).Value
    notificationTime = Cells(5, 2).Value - Cells(6, 2).Value
'Creates a string to be presented in the MsgBox
    notificationStr = Format(notificationTime, "Short Time")
    leaveStr = Format(leaveTime, "Short Time")
    nowStr = Format(nowtime, "short time")
' If it's passed the time, it will notify me
    If nowtime >= notificationTime Then
        Beep
        a = MsgBox("Agora sao " & nowStr & ". E voce tem que sair as " & leaveStr, vbExclamation, "Nao se Atase!")
    Else
        'Schedules the macro to run at the notificationTime
        Application.OnTime EarliestTime:=notificationTime, Procedure:="NotifyMe", Schedule:=True
    End If

End Sub

'Runs NotifyMe everytime a keycell is changed
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim keyCells As Range
    Set keyCells = Range("B1:B8")

    If Not Application.Intersect(keyCells, Range(Target.Address)) Is Nothing Then
        NotifyMe
    End If
End Sub

2 个答案:

答案 0 :(得分:2)

您可以使用以下模式结束预定的Application.OnTime个事件:

Public notificationTime As Date

Application.OnTime notificationTime, "NotifyMe", Schedule:=False

通过执行notificationTime公共变量,您可以使用它来引用与Schedule:=False之前计划的完全相同的过程并关闭该过程。

请试试这个,通常我是最后一个使用On Error Resume Next的人,但我认为这是最容易和最可靠的方式。

Option Explicit
Public notificationTime As Date

Sub NotifyMe()
'Declare Variables
    Dim notificationStr, leaveStr As String, a As String
    Dim nowtime As Date, leaveTime As Date, nowStr As Date
    Dim h As Long, m As Long, s As Long

    On Error Resume Next
    Application.OnTime notificationTime, "NotifyMe", Schedule:=False
    On Error GoTo 0

'Defines now Time
    h = Hour(Now())
    m = Minute(Now())
    s = Second(Now())
    nowtime = TimeSerial(h, m, s)
'Defines the time it will prompt me
    leaveTime = Cells(5, 2).Value
    notificationTime = Cells(5, 2).Value - Cells(6, 2).Value
'Creates a string to be presented in the MsgBox
    notificationStr = Format(notificationTime, "Short Time")
    leaveStr = Format(leaveTime, "Short Time")
    nowStr = Format(nowtime, "Short Time")
' If it's passed the time, it will notify me
    If nowtime >= notificationTime Then
        Beep
        a = MsgBox("Agora sao " & nowStr & ". E voce tem que sair as " & leaveStr, vbExclamation, "Nao se Atase!")
    Else
        'Schedules the macro to run at the notificationTime
        Application.OnTime EarliestTime:=notificationTime, Procedure:="NotifyMe", Schedule:=True
    End If

End Sub

同样在退出此Excel工作簿时,如果已安排任务,但其他Excel工作簿已打开,则工作簿将在计划的时间自动打开并执行代码,除非关闭工作簿时任务也被终止。如果您想阻止它,请将以下代码放在ThisWorkbook对象的代码中:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
   On Error Resume Next
   Application.OnTime notificationTime, "NotifyMe", Schedule:=False
End Sub

答案 1 :(得分:0)

在开始时使用Application.EnableEvents = false 并且在宏的末尾Application.EnableEvents = true。 当你在宏中时,它会抑制更多事件,并在你完成后启用它们。