I am coding a Stopwatch Timer in Excel, and I am trying to add a pause button that will stop the timer, also resume when clicked the 2nd time. I have it almost working, but when it resumes it does not continue the stopwatch at the same time, but rather includes all of the elapsed time. The way I have it working is that when you click the pause button it adds the value of "Paused" to a cell and sets the application to "False". If the button is clicked and the cell already says "Paused" it will empty the cell value and call the StartTimer sub and start the timer again.
Example of problem: If I press the button at 1min and 3secs, wait 3mins and resume the timer, it starts counting again at 4min and 3secs.
Example of goal: If I press the button at 1min and 3secs, wait 3mins and resume the timer, it should start counting again at 1min and 4secs.
Here is my current code that i've been working on:
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
Call StartTimer
End If
End Sub
Your code does not reset the start time when paused. But resetting the start time would lose previous elapsed periods. One approach to this problem is to record the number of elapsed seconds each time the clock stops. Subsequence start/stops are added to the running elapsed counter. There is a reset method so you can begin again from zero.
Private StartTime As Date ' Stores timer start time.
Private StopTime As Date ' Stores timer end time.
Private ElapsedTime As Integer ' Store number of seconds between start and end time.
Private TimerRunning As Boolean ' True when the timer is running.
' Resets ElapsedTime and running status.
Public Sub ResetTimer()
ElapsedTime = 0
If TimerRunning Then TimerRunning = False
End Sub
' Starts the timer.
Public Sub StartTimer()
' Record start time.
StartTime = Time
TimerRunning = True
End Sub
' Stops the timer.
' Displays elapsed seconds.
Public Sub StopTimer()
' Record end time.
StopTime = Time
TimerRunning = False
' Calculate numebr of seconds clock was running for.
' Add total to any previous runs.
ElapsedTime = ElapsedTime + DateDiff("S", StartTime, StopTime)
MsgBox "Clock ran for " & ElapsedTime & " seconds", vbInformation, "Clock Stopped"
End Sub
' Pause the timer.
Public Sub PauseTimer()
' Check current status.
If TimerRunning Then
' Stop the clock, capture the end time
' but do not reset the timer.
StopTimer
Else
' Restart the timer.
StartTimer
End If
End Sub
Users only really need access to the pause and reset functions. You could make the start and stop functions internal private methods.
I've stored the elapsed time in an integer. Date and time variables should be used to record when an event occurred, rather than the duration. Why? Because a time variable supports values from 00:00:00 -> 23:59:59 (times of the day). This leaves no room to record events that lasted longer than a day. You can always format the int when displaying.
I havn't understood how exactly your code works and I tried a couple of things but its not working. Basically what I was trying to to was to take the time from the cell M1 itself the next time it starts and then continue from there itself. Look at this code, maybe it will help.
Dim NextTick As Date, t As Date, continue_time As Date
Sub StartStopWatch()
If Range("L2").Value = "" Then
t = Time
Range("L2").ClearContents
Else
t = TimeValue(Range("M1").Text) - Time
End If
't = Time
Call StartTimer
End Sub
Sub StartTimer()
'If Range("L2").Value = "" Then
' continue_time = Time
'Else
' continue_time = TimeValue(Range("M1").Text)
'End If
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
Call StartStopWatch
End If
End Sub
I actually just figured it out using a code that counts integers and then changed the formatting to mm:ss.
Solution: http://www.ozgrid.com/forum/showthread.php?t=153966
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 worksheet which I use to track progress recording audiobooks (I'm a narrator). On each sheet, I have a timer that I use to track how many hours I record each day/session.
If the timer is running at midnight, it sets the timer to 20:00:00 and keeps going. I often am recording at midnight, so this is a major issue if I don't remember to stop the timer before midnight and restart it after.
Here is a link to the whole Excel file. You can find the timer in the TEMPLATE worksheet. The Macros for the timer are within Module1.
http://recording-tracker.narratedby.me
Here is all the code:
Option Explicit
Dim NextTick As Date, t As Date, PreviousTimerValue As Date, strSheetName As String, lRowTime As Long, lRowDate As Date, CurrentTimerValue As Date, StartTimerValue As Date
Sub StartTime()
strSheetName = ActiveSheet.Name
StartTimerValue = PreviousTimerValue
CurrentTimerValue = PreviousTimerValue
t = Time
Call ExcelstrSheetName
End Sub
Private Sub ExcelstrSheetName()
strSheetName = ActiveSheet.Name
ThisWorkbook.Worksheets(strSheetName).Range("Q1").Value = Format(Time - t + PreviousTimerValue, "hh:mm:ss")
NextTick = Now + TimeValue("00:00:01")
Application.OnTime NextTick, "ExcelstrSheetName"
End Sub
Sub StopClock()
strSheetName = ActiveSheet.Name
On Error Resume Next
Application.OnTime earliesttime:=NextTick, procedure:="ExcelstrSheetName", schedule:=False
CurrentTimerValue = ThisWorkbook.Worksheets(strSheetName).Range("Q1").Value
End Sub
Sub Reset()
strSheetName = ActiveSheet.Name
CurrentTimerValue = ThisWorkbook.Worksheets(strSheetName).Range("Q1").Value
On Error Resume Next
Application.OnTime earliesttime:=NextTick, procedure:="ExcelstrSheetName", schedule:=False
ThisWorkbook.Worksheets(strSheetName).Range("Q1").Value = 0
End Sub
The cell Q1 is what holds the timer value at any given time.
I have removed other Subs and portions of these Subs which are irrelevant to my question. This is the basic stopwatch function.
Any help is much appreciated!
Here i have my terrible code, the problem also is 25% Cpu usage when it runs and waits..
Public StopRunning As Boolean
Sub somebutton_click()
StopRunning = True
End Sub
Sub AutoOn()
Application.DisplayAlerts = False
Application.Wait (Now + TimeValue("00:14:00"))
Call Wholeshort
Application.Wait (Now + TimeValue("00:03:00"))
Call Wholeshort
Application.Wait (Now + TimeValue("00:05:00"))
Call Whole
Application.Wait (Now + TimeValue("00:22:00"))
Call Wholeshort
Application.Wait (Now + TimeValue("00:03:00"))
Call Wholeshort
Application.Wait (Now + TimeValue("00:05:00"))
Call Whole
Application.DisplayAlerts = True
If Not StopRunning Then Application.OnTime Now + TimeValue("00:08:00"), "AutoOn"
End Sub
i would like to run Macro1 every hour at xx:14,xx:17,xx:44,xx:47 minutes and Macro2 every hour at xx:22,xx:52 minutes and somehow to stop that sub by button. So when i start sub at 14:55, it will start to run 15:14,15:17,15:22 .... infinetly but can be stopped by button (how do i assign a button shortcut to stop like ctrl+x)
Is there a more efficient way to code this, and that i can start this any time, not adjust waiting minutes every time depending when i start this, i need to run this same times every hour as i wrote..
Thank you!
Try this approach, please:
Create two variables at module level (on top of it, in the declarations area):
Private StopRunning as boolean, wCount as long
All cycle can be start from the Workbook_Open() event, or from any other Sub:
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("00:14:00"), "Wholeshort"
End Sub
Then, in the module with declarations described at item 1, the next two sets of code lines must append your existing subs with their specific names:
Private Sub Wholeshort()
'existing procedure code...
'....
wCount = wCount + 1
If Not StopRunning Then
If wCount Mod 2 = 0 Then
'second time (even) it calls Whole:
Application.OnTime Now + TimeValue("00:02:00"), "Whole"
wCount = 0
Else
'first time (odd) it calls itself
Application.OnTime Now + TimeValue("00:03:00"), "Wholeshort"
End If
End If
End Sub
Private Sub Whole()
'existing procedure code...
'....
If Not StopRunning Then Application.OnTime Now + TimeValue("00:22:00"), "Wholeshort"
End Sub
In order to stop the next OnTime call, you can use your procedure:
Sub somebutton_click()
StopRunning = True
End Sub
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'm trying to set up a basic stopwatch for tracking elapsed time. Button1 should start the clock at 0, and Button2 should stop the watch and record how many minutes and seconds have elapsed since the timer started. I have the buttons lodged on a worksheet and just need a way to calculate elapsed time. What would be the best approach?
Here is the code I have been working with:
Private Sub CommandButton1_Click()
startTime = Timer
End Sub
Private Sub CommandButton2_Click()
Dim finalTime As Single
finalTime = Timer - startTime
MsgBox Format(finalTime, "0.00")
End Sub
The problem with this code is that it displays the time elapsed only after I click Button2. I need a running timer on my Excel sheet.
Public Started As Boolean
Dim myTime As Date
Sub StartTimer()
If Not Started Then
myTime = Time
Started = True
Else
If MsgBox("Do you really want to restart?", vbYesNo) = vbYes Then
myTime = Time
End If
End If
End Sub
Sub StopTimer()
If Not Started Then
MsgBox "The timer is stopped."
Else
MsgBox Format(Time - myTime, "hh:mm:ss")
Started = False
End If
End Sub
youtube
link
If you need any accuracy, Excel is probably not the place to do this. But if close enough is close enough, then here's how I would do it.
In a standard module:
Public gbStop As Boolean
Public gdtStart As Date
Sub UpdateTime()
Sheet1.Range("rngTimer").Value = Now - gdtStart
DoEvents
If Not gbStop Then
Application.OnTime Now + TimeSerial(0, 0, 1), "UpdateTime"
End If
End Sub
In Sheet1's class module
Private Sub CommandButton1_Click()
gbStop = False
gdtStart = Now
Application.OnTime Now + TimeSerial(0, 0, 1), "UpdateTime"
End Sub
Private Sub CommandButton2_Click()
gbStop = True
End Sub
When you click Button1, gbStop is set to false, the start time is recorded in a public variable, and the UpdateTime procedure is scheduled to run 1 second later.
One second later, UpdateTime runs and the value of the cell named rngTimer is changed to show the elapsed time between Now and the start recorded in Button1_Click. If gbStop is still False, UpdateTime schedules itself to run again in another second.
Eventually, you press Button2 which sets the public variable gbStop to True. The next time Updatetime runs, it doesn't schedule itself to run again.