10

Application.Ontime イベントを使用して、セルから時間フィールドを取得し、その時間に実行するサブルーチンをスケジュールしています。私の Application.Ontime イベントは Workbook_BeforeSave イベントで実行されます。そのため、ユーザーが(目的の時間を変更してブックを保存する)複数回実行すると、複数の Application.Ontime イベントが作成されます。理論的には、一意の時間変数を使用して各イベントを追跡できますが、保留中のイベントを確認/解析/キャンセルする方法はありますか?

Private Sub Workbook_BeforeSave
    SendTime = Sheets("Email").Range("B9")
    Application.OnTime SendTime, "SendEmail"
End Sub

Private Sub Workbook_BeforeClose
    Application.OnTime SendTime, "SendEmail", , False
End Sub


B9 を 12:01 に変更し、B9 を12:03
に変更したワークブックを保存し、
B9 を 12:05 に変更したワークブックを保存し、
B9 を 12:07 に変更したワークブックを保存し、ワークブックを保存します

最終的に複数のイベントが発生します。1 つのイベントのみを発生させたい (最近スケジュールされたもの)

Workbook_BeforeClose イベントですべての保留中のイベントをキャンセルする (または少なくともそれらを列挙する) にはどうすればよいですか?

4

4 に答える 4

3

保留中のすべてのイベントを反復処理したり、すべてを 1 回のシャバンでキャンセルしたりできるとは思いません。イベントを発生させるかどうかを示すモジュール レベルまたはグローバル ブール値を設定することをお勧めします。したがって、次のような結果になります。

Dim m_AllowSendMailEvent As Boolean
Sub SendMail()
If Not m_AllowSendMailEvent Then Exit Sub

'fire event here

End Sub

編集:

これを、後の日付/時刻値を含む範囲を含むシート モジュールの TOP に追加します。

' Most recently scheduled OnTime event. (Module level variable.)
Dim PendingEventDate As Date

' Indicates whether an event has been set. (Module level variable.)
Dim EventSet As Boolean

Private Sub Worksheet_Change(ByVal Target As Range)

Dim SendTimeRange As Range

' Change to your range.
Set SendTimeRange = Me.Range("B9")

' If the range that was changed is the same as that which holds
' your date/time field, schedule an OnTime event.
If Target = SendTimeRange Then

    ' If an event has previously been set AND that time has not yet been
    ' reached, cancel it. (OnTime will fail if the EarliestTime parameter has
    ' already elapsed.)
    If EventSet And Now > PendingEventDate Then

        ' Cancel the event.
        Application.OnTime PendingEventDate, "SendEmail", , False

    End If

    ' Store the new scheduled OnTime event.
    PendingEventDate = SendTimeRange.Value

    ' Set the new event.
    Application.OnTime PendingEventDate, "SendEmail"

    ' Indicate that an event has been set.
    EventSet = True

End If

End Sub

そしてこれを標準モジュールに:

Sub SendEmail()

    'add your proc here

End Sub
于 2011-01-05T01:24:58.373 に答える
1

または、いくつかのセル (そろばんなど) を作成することもできます。たとえば、次のようになります。

application.ontime を使用する場合:

if range("V1") < 1 then

    Application.OnTime dTime, "MyMacro"

    range("V1")=range("V1") + 1

 end if

カウントをやめたい場合...

   Application.OnTime dTime, "MyMacro", , False

   range("V1")=range("V1") - 1
于 2011-11-15T09:23:44.373 に答える
1

すでに与えられたアドバイスのいくつかに基づいて、うまくいく解決策があると思います。

saveつまり、グローバル配列を作成し、ユーザーが SendTime をヒットするたびに配列に書き込まれます。これは、スケジュールされたすべての時間を追跡するのに役立ちます。

ワークブックが閉じられると、配列をループして、スケジュールされたすべての時間を削除します。

これをテストしたところ、Excel 2003 で動作するように見えました。

Dim scheduleArray() As String //Set as global array to hold times

Private Sub Workbook_BeforeSave
    SendTime = Sheets("Email").Range("B9")
    AddToScheduleArray SendTime
    Application.OnTime SendTime, "SendEmail"
End Sub

Private Sub Workbook_BeforeClose
    On Error Resume Next
    Dim iArr As Integer, startTime As String

    For iArr = 0 To UBound(scheduleArray) - 1 //Loop through array and delete any existing scheduled actions 
        startTime = scheduleArray(iArr)
        Application.OnTime TimeValue(startTime), "SendEmail", , False
    Next iArr
End Sub

Sub AddToScheduleArray(startTime As String)
    Dim arrLength As Integer

    If Len(Join(scheduleArray)) < 1 Then
        arrLength = 0
    Else
        arrLength = UBound(scheduleArray)
    End If

    ReDim Preserve scheduleArray(arrLength + 1) //Resize array
    scheduleArray(arrLength) = startTime //Add start time
End Sub
于 2011-01-10T19:27:22.340 に答える
1

Application.Ontime を呼び出すたびに、イベントが実行されるように設定された時間を保存します (シートまたはモジュール スコープの動的配列に保存できます)。

イベントが発生するたびに、対応する保存時間を削除します

保留中のすべてのイベントをキャンセルするには、スケジュール = false で Application.Ontime を呼び出して、保存された残りの時間を繰り返します。

于 2011-01-05T09:39:42.920 に答える