I have built a small 5 minute Countdown in a UserForm.
The countdown should count down. But if the UserForm is closed, the macro should stop and the timer should be reset.
In the UserForm's Terminateevent I have stored the call of my own abort function. This terminates the UserForm, but the timer continues to run in the background and the corresponding macro is always brought to the foreground.
How can the code be modified to stop the timer when the UserForm is closed?
Module 1
Dim Count As Date
Sub callBreak()
Break.Show
End Sub
Sub Time()
Count = Now + TimeValue("00:00:01")
Application.OnTime Count, "minus"
End Sub
Sub minus()
Dim y As Date
y = Break.Label1.Caption
y = y - TimeSerial(0, 0, 1)
Break.Label1.Caption = y
If y <= 0 Then
Break.Label1.Caption = "Arbeit, Arbeit!"
Exit Sub
End If
Call Time
End Sub
Sub abord()
End
End Sub
Userform:
Sub UserForm_Initialize()
Call Coffeebreak.Time
End Sub
Sub UserForm_Terminate()
Call Coffeebreak.abord
End Sub
You can cancel a previously scheduled procedure by setting the optional Schedule argument of Application.OnTime to False. Try this as your Abord() function:
Sub Abord()
Application.OnTime EarliestTime:=Count, Procedure:="minus", Schedule:=False
End Sub
One solution:
in your module, define a global boolean variable, eg isCancelled. Set this variable to true in abort and check it in minus to prevent that the timer is called again.
Dim Count As Date
Dim isCancelled as Boolean
Sub Time()
isCancelled = False
Count = Now + TimeValue("00:00:01")
Application.OnTime Count, "minus"
End Sub
Sub minus()
if isCancelled Then Exit Sub
(...)
End Sub
Sub abort()
isCancelled = True
End Sub
Related
I am trying to run multiple timers in different cells in MS excel. I want to stop the timer only on the selected active cell.
The problem is when I am starting the timer on another cell. The previous timer on a previously chosen cell automatically stops.
The program I have now starts the timer upon double clicking.
I am trying to run different timers on the different cells and I want to stop the timer on the selected cells only using macros.
Here is what I have done so far:
The functions have been assigned to macros.
For a clearer explanation, let's say I start the timer in Cell A1 by double clicking(as coded in my worksheet). Now, if I start the timer in Cell A2, then the timer in A1 stops, and the timer in A2 runs. I want to run both the timers and stop the timer on the cell I select only while the other should still run.
I am scratching my head as to how I should modify my code to achieve this.
Option Explicit
Dim Tick As Date, t As Date
Global myCell As Range
Sub stopwatch()
t = Time
Call StartTimer
End Sub
Sub StartTimer()
Tick = Time + TimeValue("00:00:01")
myCell.Value = Format(Tick - t - TimeValue("00:00:01"), "hh:mm:ss")
Application.OnTime Tick, "StartTimer"
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=Tick, Procedure:="StartTimer", Schedule:=False
End Sub
In my Worksheet , I have this code to start the timer on double click:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Set myCell = Target
StartTimer
Cancel = True
End Sub
Try this - using a Dictionary to track which cells have timers running.
Double-click a cell to start a timer there: double-click again to stop.
This code is all in the Sheet3 module (codename)
Option Explicit
Dim timers As Object 'cell addresses as keys and start times as values
Dim nextTime 'next run time
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
ToggleTimer Target
Cancel = True
End Sub
Sub ToggleTimer(Optional c As Range = Nothing)
Dim addr As String, k, macro
If timers Is Nothing Then Set timers = CreateObject("scripting.dictionary")
macro = Me.CodeName & ".ToggleTimer"
On Error Resume Next 'cancel any running timer
Application.OnTime EarliestTime:=nextTime, Procedure:=macro, Schedule:=False
On Error GoTo 0
If Not c Is Nothing Then '? called from a cell double-click ?
addr = c.Address(False, False)
If timers.exists(addr) Then
timers.Remove addr ' timer was running - remove it
Else
timers(addr) = Now ' timer was not running - add it
End If
End If
If timers.Count = 0 Then Exit Sub 'no more timers
For Each k In timers 'update timer(s)
Me.Range(k).Value = Format(Now - timers(k), "hh:mm:ss")
Next k
'schedule next run
nextTime = Now + TimeSerial(0, 0, 1)
Application.OnTime nextTime, Me.CodeName & ".ToggleTimer"
Debug.Print Me.CodeName
End Sub
I have a code to set a timer of 5 minutes on my userform. It works when I press the command button.
How do I make it run automatically at the start ? I tried in ThisWorkbook but it didn't worked.
here's the code :
In a module:
Public Const AllowedTime As Double = 1
In the Userform:
Private Sub CommandButton1_Click()
Dim userClickedPause As Boolean ' Gets set to True by the Pause button
Dim stopTime As Date
userClickedPause = False
' If AllowedTime is the number of minutes with a decimal part:
stopTime = DateAdd("s", Int(AllowedTime * 600), Now) ' add seconds to current time
' If AllowedTime is the number of seconds:
'stopTime = DateAdd("s", AllowedTime, Now) ' add seconds to current time
Do
With UserForm1.TextBox1
.Value = Format(stopTime - Now, "Nn:Ss")
End With
DoEvents
If userClickedPause = True Then
Exit Do
End If
Loop Until Now >= stopTime
End Sub
Private Sub CommandButton2_Click()
userClickedPause = True
End Sub
I would recommend you to re-structure your code. Since you want to call your StartTimer sub from both a UserForm and the Workbook_Open event, put it into a module.
Then you simply call the sub from your Commandbutton1_Click event and the Workbook_Open event.
'Put this code inside ThisWorkbook
Private Sub Workbook_Open()
'This sub into ThisWorkbook
Application.Run "SetTimer"
End Sub
'This sub goes into a module
Private Sub SetTimer()
'Here goes your code that sets the timer
'(move it from your UserForm)
'.......................................
'.......................................
End Sub
'The code inside your UserForm
Private Sub CommandButton1_Click()
Application.Run "SetTimer"
End Sub
I've got three Subs in Module: runClock, startClock and stopClock.
runClock is showing a clock that is updated every 5 seconds.
startClock is used to start the clock and is called from Sub Workbook_Open.
stopClock - is used to stop the clock and is called from Sub Workbook_BeforeClose.
However, when ever I close the workbook, it reopens automatically and the clock continues to run. I've checked the value of ClockOn and it's set to FALSE after the Workbook_BeforeClose is executed. I think that that issue has to do with Application.OnTime, but don't know how to fix it.
This Code is in Module:
Global ClockOn As Boolean
Sub runClock()
With Range("A1")
.Value = Now()
.NumberFormat = "hh:mm:ss"
If ClockOn = True Then
Application.OnTime Now + TimeSerial(0, 0, 5), "runClock"
End If
End With
End Sub
Sub startClock()
ClockOn = True
runClock
End Sub
Sub stopClock()
ClockOn = False
End Sub
This Code is in ThisWorkbook:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
stopClock
ActiveWorkbook.Save
End Sub
Private Sub Workbook_Open()
startClock
End Sub
This seems to be happening because the times resulting from Application.OnTime are not the same. The initial call time should be saved as a variable and then referenced in the subs. See this solution.
https://www.ozgrid.com/forum/forum/help-forums/excel-general/131658-timer-reopens-workbook-when-closed
Found a solution in http://www.cpearson.com/excel/OnTime.aspx
I've changed my sub stopClock so now it includes the following code:
RunWhen = Now + timeserial(0, 0, 5)
Application.OnTime earliestTime:=RunWhen, Procedure:="startClock", Schedule:=False
This stops the clock from running and the workbook from reopening.
I don't know what caused it to reopen under the previous code, but at least now it's fine.
I have a stopwatch with a start/stop/clear button that posts the time to other cells in my spreadsheet. I want to add a pause button to allow users to pause and resume the timer where they left off, but it kept resuming and adding the time passed in the interim to the total. For example, I hit start and wait 5 minutes, then click pause at 5:00. I wait 2 more minutes, then click resume, and the timer picks back up at 7:00, 7:01, 7:02, etc. How do I create an effective pause/resume button and tell excel not to include the time passed when it resumes counting?
Dim NextTick As Date, t As Date
Sub StartStopWatch()
t = Time
Call StartTimer
End Sub
Sub StartTimer()
NextTick = Time + TimeValue("00:00:01")
Range("M1").Value = Format(NextTick - t - TimeValue("00:00:01"), "hh:mm:ss")
Application.OnTime NextTick, "StartTimer"
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=NextTick, Procedure:="StartTimer", Schedule:=False
End Sub
Sub ResetTimer()
Range("M1").ClearContents
Range("N1").ClearContents
Range("L2").ClearContents
End Sub
Sub PauseButton()
If Range("L2").Value = "" Then
Range("L2").Value = "Paused"
Application.OnTime EarliestTime:=NextTick, Procedure:="StartTimer", Schedule:=False
Else
Range("L2").ClearContents
Application.OnTime EarliestTime:=NextTick, Procedure:="StartTimer", Schedule:=True
End If
End Sub
I think like this
Public blResume As Boolean
Dim NextTick As Date, t As Date
Sub StartStopWatch()
t = Time
Call StartTimer
End Sub
Sub StartTimer()
NextTick = Time + TimeValue("00:00:01")
Range("M1").Value = Format(NextTick - t - TimeValue("00:00:01"), "hh:mm:ss")
If blResume = False Then Exit Sub
Application.OnTime NextTick, "StartTimer"
End Sub
Sub Pause()
blResume = False
End Sub
Sub myResume()
blResume = True
StartTimer
End Sub
I am french so sorry for my english i do my best...
I try to call a sub named timer1_tick and i want it to stop my sub "b_reponse1_click". The problem is that my sub dont wait until the end of the timer...
Code:
Sub Process_Globals
Dim Timer1 As Timer
....
End Sub
Sub Activity_Create(FirstTime As Boolean)
Timer1.Initialize("Timer1", 1000) ' 1000 = 1 second
Timer1.Enabled = True
...
End Sub
Sub b_reponse1_Click
p= p + 1
If b_reponse1.Text = r5 Then
score = score + 1
b_reponse1.Color=Colors.Green
CallSub("",timer1_tick) ' Here i call sub timer1_tick
b_reponse1.Color=Colors.Gray
Else
b_reponse1.Color=Colors.Red
b_reponse1.Color=Colors.Gray
End If
If nbqpassee = 10 Then
Activity.RemoveAllViews
Activity.LoadLayout("lay_main")
Else
CallSub("",loadq)
End If
End Sub
Timer1 countdown but my sub b_reponse1_Click continue execution without waiting the end of timer
Timer :
Code:
Sub timer1_tick
t = t + 1
Log(t)
End Sub
I have try this but didn't solve my problem :
Code:
Sub timer1_tick
t = t + 1
Log(t)
timer1.Enabled = False
End Sub
Do you know how can i do to stop my sub b_reponse1_click about to 1 second ?
Thanks by advance for answer !
timer1_tick is a regular sub like any other sub. It will not cause the code execution to wait.
Search the forum for CallSubPlus. You can break your current sub to two subs and then call the second sub with CallSubPlus which will run after the specified time.