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.
Related
I asked a similar question yesterday, and I got an answer but now I am having a different problem with the solution that I found.
I have some excel code, and I have it setup to autosave. And it is setup to autosave on a timer. I want to be able to have that timer reset whenever I manually save the project, but it doesn't seem to be working.
I am using the Workbook_BeforeSave command to do something (ideally reset the timer) before saving. That way if I manually save the workbook, it will start that timer over again.
I tried something like this:
Workbook:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, _
Cancel As Boolean)
Call StopTimer
End Sub
Module:
Public Sub StartTimer()
RunWhen = Now + TimeValue("00:00:10")
cRunWhat = "AutoSave"
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=True
End Sub
Public Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=False
End Sub
But that does not seem to work. I even tried a simplified version, where I start a timer, and then just manually run StopTimer, and it doesn't stop the timer.
Is there something that I am missing on how StopTimer() should be working?
Thanks for any help!
Edit: Solution I used
I was able to accomplish what I wanted using the following methods.
In the Workbook
I used the function Workbook_BeforeSave() in order to stop the timer after being saved.
Private Sub Workbook_BeforeSave(ByVal SaveAsUi As Boolean, _
Cancel As Boolean)
Call StopTimer
End Sub
This is calling the Module StopTimer(). Which is defined on the Module level.
Option Explicit
Public RunWhen
Public cRunWhat
Public Sub StartTimer()
RunWhen = Now + TimeValue("00:01:00")
cRunWhat = "Save"
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=True
End Sub
Public Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=False
StartTimer
End Sub
Now, I had a different function in the workbook calling StartTimer, and Save() was just a basic save the workbook function.
The main issue I was having was solved here. But the other post I made helped me through it a little bit as well. Linked here
The solution is copied here.
First off, check that your Module starts with the magic line Option Explicit - this means that Excel will throw an error if you haven't explicitly defined a Variable before trying to use it. Otherwise, it will treat it as a blank value by default. There is actually a tickbox under Tools / Options ("Require Variable Declaration") to automatically shove this at the top of all your modules.
Without:
Sub BadCode()
MsgBox 10 + NotAVariable
End Sub
10
With:
Option Explicit
Sub BadCode()
MsgBox 10 + NotAVariable
End Sub
Compile Error:
Variable not defined
Next, make sure that your Variables are defined at a module level, not in a Sub or Function - this means that other Subs and Functions can "see" the variable:
Without:
Sub Part1()
Dim SomeNumber AS Long
SomeNumber = 4
End Sub
Sub PartB()
MsgBox 10 + SomeNumber
End Sub
Compile Error:
Variable not defined
With:
Dim SomeNumber AS Long
Sub Part1()
SomeNumber = 4
End Sub
Sub PartB()
MsgBox 10 + SomeNumber
End Sub
14
You can use Dim SomeNumber, Public SomeNumber or Private SomeNumber - using Public will let other modules "see" the variable too, while Private will only let code in that specific module "see" it.
I had a similar issue where I was saving after the end of every line- but wanted to reset the autosave timer to x seconds in the future when I am editing multiple lines.
The Marco reports !Save function not available. Substituted with one of my SaveasXLSB Macros and it worked.
I am hoping this keeps kicking the can down the road so to speak so when the system is idle for that amount of time /then/ it saves...
Option Explicit
Public RunWhen
Public cRunWhat
Public Sub StartTimer(Optional StrTimevalue As String = "00:00:10")
RunWhen = Now + TimeValue(StrTimevalue)
cRunWhat = "SaveAsDefaultXLSB"
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=True
End Sub
Public Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=False
StartTimer ""
End Sub
So, I have some code autosaving my Excel project. I am looking for a way to stop / reset the autosave timer when the document is saved manually. This is what I am using for the autosave.
If ThisWorkbook.Name = "mydoc.xlsm" Then
Application.OnTime Now + TimeValue("00:30:00"), "Save_Workbook"
End If
I tried an if statement:
If ActiveWorkbook.Saved = False Then
Application.OnTime Now + TimeValue("00:01:00"), "ShowMsg"
End If
To see if by saving the document I would stop ShowMsg from going off. But even after saving the document, ShowMsg goes off at the 1 minute mark. It doesn't change the timer.
Edit: Solution I used
I was able to accomplish what I wanted using the following methods.
In the Workbook
I used the function Workbook_BeforeSave() in order to stop the timer after being saved.
Private Sub Workbook_BeforeSave(ByVal SaveAsUi As Boolean, _
Cancel As Boolean)
Call StopTimer
End Sub
This is calling the Module StopTimer(). Which is defined on the Module level.
Option Explicit
Public RunWhen
Public cRunWhat
Public Sub StartTimer()
RunWhen = Now + TimeValue("00:01:00")
cRunWhat = "Save"
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=True
End Sub
Public Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, Schedule:=False
StartTimer
End Sub
Now, I had a different function in the workbook calling StartTimer, and Save() was just a basic save the workbook function.
A main issue I was having was solved in another post, by me. Linked here
I will be copying this solution to that post.
You could use the BeforeSave event.
https://learn.microsoft.com/en-us/office/vba/api/excel.workbook.beforesave
Something like:
In ThisWorkbook:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, _
Cancel as Boolean)
Call Timer
End Sub
In Module:
Sub Timer()
Application.OnTime Now + TimeValue("00:00:03"), "Hello"
End Sub
Sub Hello()
MsgBox "Hello"
End Sub
I am using this VBA code to refresh my entire workbook at specific time intervals. (thanks to this thread)
As you can see, it is currently set to refresh every 60 minutes.
Public RunWhen As Double
Public Const cRunIntervalMinutes = 60
Public Const cRunWhat = "Workbook_RefreshAll"
Sub StartTimer()
RunWhen = Now + TimeSerial(0, cRunIntervalMinutes, 0)
Application.OnTime earliesttime:=RunWhen, procedure:=cRunWhat, _
schedule:=True
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime earliesttime:=RunWhen, _
procedure:=cRunWhat, schedule:=False
End Sub
Sub Workbook_RefreshAll()
Application.CalculateFullRebuild
ActiveWorkbook.RefreshAll
Call StartTimer
End Sub
The code works great, however there’s one thing I wish it could also do:
Any time the sheet is opened, and/or
Any time this VBA code executes the sheet refresh process
I would like the AutoFilter to be "Cleared" (not disabled or turned off) as in the screen grab below:
AutoFilter Clear
Thanks in advance for any assistance.
Cheers
This should do the trick. You may of course do it for one Sheet only, if you wish.
Sub Workbook_RefreshAll()
Dim sh As Worksheet
Application.CalculateFullRebuild
ActiveWorkbook.RefreshAll
For Each sh In ActiveWorkbook.Worksheets
If Not (sh.AutoFilter Is Nothing) Then sh.AutoFilter.ShowAllData
Next sh
Call StartTimer
End Sub
By using the below code RefreshData I run mg macro every 10 secs.
I'm unable to stop stoprefresh which is assigned to a square shape.
Sub RefreshData()
Application.OnTime Now + TimeValue("00:00:10"), "mg", , True
End Sub
Sub stoprefresh()
On Error Resume Next
Application.OnTime Now + TimeValue("00:00:10"), "mg", , False
End Sub
Sub mg()
ActiveSheet.Cells(ActiveSheet.Cells.Rows.Count, 1).End(xlUp).Offset(1) = "Running"
Call RefreshData
End Sub
Try this code
Option Explicit
Dim iTimerSet As Double
Sub RefreshData()
iTimerSet = Now + TimeValue("00:00:10")
Application.OnTime iTimerSet, "mg", , True
End Sub
Sub stoprefresh()
'On Error Resume Next
Application.OnTime iTimerSet, "mg", , False
End Sub
Sub mg()
ActiveSheet.Cells(ActiveSheet.Cells.Rows.Count, 1).End(xlUp).Offset(1) = "Running"
Call RefreshData
End Sub
Cancelling a scheduled Procedure
It is possible to cancel a procedure that has been scheduled to run but you need to know the
exact date and time it was scheduled for. To cancel a scheduled
procedure you must know the "EarliestTime" it was scheduled for.
Exactly the same syntax except you set the schedule paramater to
False. This tells the application to cancel the schedule.
I'm using Excel 2010, and want to create a countdown timer in excel. The code will be started and stopped by using buttons with macros attached to them. The problem occurs when the "start" button is pushed. The code above is utilizing Cell "B1" as the input spot, because I was just trying to get it to work, but every time I tried, it would always say:
"Cannot run the macro . The macro may not be available in this workbook or all macros may be disabled".
Yes I enabled all macros before putting this here. I want to be able to take user input, and to make that the time that the timer starts at instead of just using cell "B1".
'Macro for Starting the timer (attached to the start button)
Sub startTimer()
Application.OnTime Now + TimeValue("00:00:01"), "nextTick"
End Sub
'Macro for next second
Sub nextTick()
Sheet1.Range("B1").Value = Sheet1.Range("B1").Value - TimeValue("00:00:01")
startTimer
End Sub
'Macro for stopping the timer (attached to the end button)
Sub stopTimer()
Application.OnTime Now - TimeValue("00:00:01"), "nextTick", , False
End Sub
I modified your code very slightly and put it in a standard module:
Public Future As Double
Sub StartTimer()
Future = Now + TimeSerial(0, 0, 1)
Application.OnTime earliestTime:=Future, procedure:="nextTime", _
schedule:=True
End Sub
Sub nextTime()
Sheet1.Range("B1").Value = Sheet1.Range("B1").Value - TimeValue("00:00:01")
StartTimer
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime earliestTime:=Future, _
procedure:="nextTime", schedule:=False
End Sub
Both StartTimer() and StopTimer() run just fine.