Application.OnTime isn't running automatically - excel

I'm trying to close my workbook after a certain amount of time.
I'm using 10 seconds for now just to test it but it's not working automatically.
I have to run the code once by myself.
here's my code in module.
Public Sub fermeoutil()
Workbooks("OUTIL_CRN.xlsm").Save
Workbooks("OUTIL_CRN.xlsm").Close
Call test
End Sub
Sub test()
Application.OnTime Now + TimeValue("00:00:10"), "fermeoutil"
End Sub

In ThisWorkbook add procedure Workbook_Open with following code:
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("00:00:10"), "fermeoutil"
End Sub
In Module1 keep your current procedure fermeoutil() removing the call to test:
Public Sub fermeoutil()
Workbooks("OUTIL_CRN.xlsm").Save
Workbooks("OUTIL_CRN.xlsm").Close
End Sub
Your call to test (or Workbook_Open() as it is now called), is not needed, as you have left out the last argument of Application.OnTime, namely Schedule which is optional and has a default value of True meaning the event will be recurring. Not sure if that really is your meaning, since you are closing the wb.

Related

Excel macro call does not work from timer, but does from another macro

I am trying to get excel to run an update every XX seconds.
Sub StartTesting()
Call RunAll_ISP 'this call works
End Sub
Sub macro_timer() 'This sub schedules next run in XX seconds.
Dim ScanInterval
ScanInterval = Format(ThisWorkbook.Sheets("Configuration").Range("B5").Value, "hh:mm:ss")
Application.OnTime Now + TimeValue(ScanInterval), "RunAll_ISP", Schedule:=True ' !this macro call throws error!
End Sub
If I run Start_testing macro, call works.
If I run macro_timer macro, it waits desired number of seconds, and then throwsthis error:
Cannot run the macro "C:\location_of_file\filename.xlsm'!RunAll_ISP'. The macro may not be available in this workbook or all macros may be disabled
The settings for macros in the Trust center are set to "Enable VBA macros"
What am I doing wrong?
Your problem cannot be reproduced. This simple Example works.
So since your procedure StartTesting worked that means macros are definitely enabled, so the only option left is that your macro RunAll_ISP does not exist (or wrongly named).
Option Explicit
Public Sub RunAll_ISP()
MsgBox "I run"
End Sub
Public Sub CreateTimer()
Application.OnTime Now + TimeValue("00:00:05"), "RunAll_ISP", Schedule:=True
End Sub

Excel Function 'Application.OnTime' still running after closing the workbook

I am using Excel (Office 365).
here is a video with my problem: link
The internet is full of examples where people say that the code should work when we set Schedule to False but sadly that did not help me.
The code should start a cycle using Application.OnTime and stop it before closing the workbook.
If I run the function stopF manually, in the VBA Editor, it stops Application.OnTime properly.
But if I close the workbook, it still opens up and continues executing Application.OnTime.
' In Module1:
Public startingTime As Double
Sub startF()
MsgBox "hello"
startingTime = Now + TimeValue("00:00:10")
Application.OnTime startingTime, "Module1.startF"
End Sub
Sub stopF() 'HERE IT WORKS GOOD
On Error Resume Next
Application.OnTime startingTime, "Module1.startF", , False
End Sub
' In ThisWorkbook:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call stopF 'HERE IT DOES NOT WORK GOOD
End Sub
I don't have a clue what could I do more.
My temporary solution to my question:
I left the whole code like it was and added into Module1 following code:
' In Module1:
Sub closeWorkbook()
Call stopF
ThisWorkbook.Close
End Sub
The point is:
for manual closing stopF called from Workbook_BeforeClose will work
for vba closing stopF called from a module will work.
A bit more detailed:
when a user closes a workbook manually (closes the Excel window) then Workbook_BeforeClose => Call stopF will be triggered and it will stop Application.OnTime properly.
if I want to close the workbook via code then I do not rely on the Workbook_BeforeClose function (because it doesn't work for this somehow) but I call my new closeWorkbook() function when needed, which does terminate Application.OnTime and then closes the workbook.

Auto-save in VBA is reopening closed files

I implemented some code into a few of my excel sheets that would cause the file to autosave periodically. The issue I am running into with the code, is that when it is executed, it reopens the files that have been closed that also contain the same code.
I am looking for a way to have VBA autosave documents every so often, but it would no longer run if the file isn't open.
This is the code I have implemented:
Contained in "ThisWorkbook":
Private Sub Workbook_Open()
Application.OnTime Now + TimeValue("03:00:00"), "Save1"
End Sub
Contained in "Module 3":
Sub Save1()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
Application.OnTime Now + TimeValue("03:00:00"), "Save1"
End Sub
A note: The code between all of the documents is 100% identical (except the TimeValue, which varies by a few hours among some of them).
Try the next approach, please:
Adapt the OnTime call to a better qualified Sub:
Private Sub Workbook_Open()
scheduleTime = Now + TimeValue("03:00:00")
Application.OnTime scheduleTime, "Module3.Save1"
End Sub
Make the Sub in discussion Private, and create a new Public variable on top of the module:
Public scheduleTime As Date
Private Sub Save1()
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
scheduleTime = Now + TimeValue("03:00:00")
Application.OnTime scheduleTime, "Module3.Save1"
End Sub
Clear the already set OnTime procedure:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime scheduleTime , "Module3.Save1", , False
End Sub
The first two items will solve the opening of other workbooks when the active workbook procedure is called. But, this should not happen and I am afraid that this is not the real opening mechanism, the workbooks are open by their own OnTime function call.
If my above supposition is True, the item 3 alone will solve the issue...
As you may notice, OnTime is an Application method, not a Workbook method.
This means that, even if you close the Workbook, so long as the Excel Application is still open that OnTime is still counting down. Once it hits zero, it will try to run the Subroutine - but the workbook is closed. Rather than throw an Error, Excel will reopen the Workbook, and then run the Subroutine.
In order to stop this, you will need to unscheduled the Subroutine before you close the Workbook, which will also mean Storing the time. So, you will need a Module that looks something like this:
Option Private Module
Option Explicit
Private AutoRunTime AS Date
Public Sub AutoSaveWorkbook()
ThisWorkbook.Save
AutoRunTime = Now()+TimeSerial(3,0,0) '3 hours
Application.OnTime AutoRunTime, "AutoSaveWorkbook", True
End Sub
Public Sub CancelAutoSave()
Application.OnTime AutoRunTime, "AutoSaveWorkbook", False
End Sub
Then, in the Workbook_Open even you call AutoSaveWorkbook to start things off, and in the Workbook_BeforeClose even you call CancelAutoSave to end them

StopTimer() Not working. Need a way to restart my timer in excel

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

VBA Saving delay after data entry

VBA newbie here. I am looking for a way that will allow my excel file to automatically save after a delay of 1 min after data input.
For example:
User Inputs Data --> Timer Starts (1min)
5 seconds passes.
User inputs Data --> Timer Restarts (1min)
1 min passes.
Excel File Saves - until the user starts inputting data again
Any thoughts?
One possibility is to leverage the Workbook.SheetChange event and Application.OnTime. You'll also need a Public variable, ScheduledTime in the example below.
Every time any (non-chart) sheet is changed (e.g. via data entry):
Any previously scheduled save, as long as it's still within the one-minute window, is cancelled.
A new save is scheduled for one minute out.
So something like the following:
In the ThisWorkbook code module:
Option Explicit
Public ScheduledTime
Private Sub Workbook_SheetChange(ByVal Sh As Object, _
ByVal Target As Range)
On Error Resume Next
Application.OnTime EarliestTime:=ScheduledTime, Procedure:="SaveTheFile", Schedule:=False
On Error GoTo 0
ScheduledTime = Now + TimeValue("00:01:00")
Application.OnTime EarliestTime:=ScheduledTime, Procedure:="SaveTheFile"
End Sub
In a regular code module:
Public Sub SaveTheFile()
ThisWorkbook.Save
End Sub
You could just as well use the Worksheet Change event if you want to restrict this to a particular sheet.
I have a similar take on this to BigBen.
In ThisWorkbook module:
Option Explicit
Public SnapShot As String
Private Sub Workbook_Open()
StartTimer
End Sub
Sub StartTimer()
If SnapShot = vbNullString Then SnapShot = Now
If DateDiff("s", SnapShot, VBA.CStr(Now)) >= 10 Then ThisWorkbook.Save
RestartTimer
End Sub
Sub RestartTimer()
Application.OnTime Now + TimeValue("00:00:10"), "ThisWorkbook.StartTimer"
End Sub
And then in the worksheet you are monitoring:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
ThisWorkbook.SnapShot = Now
End Sub

Resources