How to intermittently run two macros in a module (two subprocesses) and we have a latency (wait time for example 700 seconds) to request user to change the position of cursor to the desirable location and then second macro will be run based on new position of cursor
Sub Main()
'Here you execute or run the 1st macro
call Macro1
'Now we inform the user with a messagebox
'for the next action they have to take
'and the time limit within which to complete the action
'after closing the msgbox
msgbox "You have 10 seconds after you close this to move your mouse."
dim WaitUntil
WaitUntil=Now+timeserial(0,0,10)
'Wait a certain amount of time
do while now<=WaitUntil
doevent
loop
'Now user must have completed the manual action
'so we can proceed with the second Macro
call Macro2
End Sub
Sub Macro1()
'code
End Sub
Sub Macro2()
'code
End Sub
Related
i currently have 5 macros, they refresh my data, macro1 refresh data from sheet1, macro2 refreshes data from sheet2 and so on untill sheet5, each sheet has its own macro to refresh its own sheets data. So what i need is when marco1 starts, wait one minute before running macro2, "macro2 finishes", waite one minute before runing macro3 ans so on till last macro, then i can start the sequence, or stop it an any time via the buttons. It is data from the web in excel, i have tried going to table properties but have been unable to refresh all 5 tables at time intervals as explained previously.
Any help here is highly appreciated.
Try this approach, please:
Sub testMacro1()
'your code here
Application.OnTime Now + TimeValue("00:01:00"), "testMacro2"
End Sub
Sub testMacro2()
'your code here
Application.OnTime Now + TimeValue("00:01:00"), "testMacro3"
MsgBox "Macro2"
End Sub
Sub testMacro3()
'your code here
MsgBox "Macro3"
End Sub
It will run 'testMacro2' after a minute, then 'testMacro3' after another minute. You can extrapolate the idea up to your 'Macro5' Sub...
I have a workbook that crashes Excel on close when the close is triggered by an API timer.
Edit: The workbook in link below has nothing but the timer and exit modules and it has the same behavior so it's not an issue with the content.
https://www.dropbox.com/s/x0xdwgj5h34ctdk/Book1.xlsm?dl=0
A few seconds after the workbook closes Excel crashes. I have tried turning the timer off, unhiding all sheets, unloading forms...all the objects are set to Nothing.
All I am doing is Workbooks(ThisWorkbook.Name).Close SaveChanges:=True??!!
The same sub is called from a UserForm with no problem. The workbook closes without Excel crashing.
How to fix this?
Sub ApplicationExit()
' Call UnloadAllForms
' DoEvents
' Sleep 1000
' Call StopCloseTimer
'DoEvents
'If Application.Workbooks.Count = 1 Then
' Workbooks(ThisWorkbook.Name).Save
' Application.Quit
'Else
DoEvents
Workbooks(ThisWorkbook.Name).Close SaveChanges:=True
'End If
End Sub
The code triggered by the timer is;
Sub TimerCalled()
If CloseTimerValue = "" Then Call Reset_CloseTimerValue
DoEvents
If basTimers.CloseTimerValue <= Now() And Not Unlocked Then Call ApplicationExit
On Error Resume Next 'In case sheet is protected
ThisWorkbook.Sheets("JobIndex").Range("CloseCount").Value = Format(Now() - CloseTimerValue, "hh:m:s")
End Sub
The userform says;
CloseUp:
i = MsgBox("Close Project Register?", vbYesNo, MsgBoxTitle)
Select Case i
Case vbYes
Call ApplicationExit
Case vbNo
Workbooks(ThisWorkbook.Name).Save
End Select
Timer in excel vba is done by using the Application.OnTime command or windows timer, as you are using.
Notice that, to schedule the call for a function (using the upper-mentioned command), it's used APPLICATION, which means it tells EXCEL to execute the call, not your workbook. So, in your case, the workbook is closed, BUT the to-be-called procedure is still scheduled to go off at some time in the future. The error that you get is that the excel doesn't find the procedure and then throws an error.
The reason it crashes in your case is that you are using windows timer to do it. When you close your workbook, your instance of the lib32 is lost and when time comes, Windows can't reach in the memory and then crashes the whole application.
In both cases, it seems that your scheduled procedure is still running.
I suggest that you look into that and consider using application.ontime.
I want to monitor a value and get an email notifications when certain conditions are met. I have a macro like so:
Do While True
Worksheet.Calculate
If Value > 10 Then
SendEmail
End If
Sleep 60*CLng(1000)
Loop
However, when I run this, it clogs up the entire program and will turn unresponsive if I try to do anything.
Is there anyway to accomplish this but have it run in the background or at least not crash the program?
What I was doing before was using VBScript to open a not-visible spreadsheet and the VBScript ran continuously in the background monitoring the condition and worked fine, but my client really wants a GUI and for it to be in the program itself.
Any thoughts?
Use the Application.OnTime method to schedule code that will run in one minute.
Your code will look something like this (Untested):
Sub CreateNewSchedule()
Application.OnTime EarliestTime:=DateAdd("n", 1, Now), Procedure:="macro_name", Schedule:=True
End Sub
Sub macro_name()
If Value > 10 Then
SendEmail
Else
CreateNewSchedule
End If
End Sub
You might want to store the time of the next schedule in a global variable so that the Workbook_BeforeClose event can cancel the next schedule. Otherwise Excel will re-open the workbook.
Public nextScheduledTime As Date
Sub CreateNewSchedule()
nextScheduledTime = DateAdd("n", 1, Now)
Application.OnTime EarliestTime:=nextScheduledTime , Procedure:="macro_name", Schedule:=True
End Sub
Sub macro_name()
If Value > 10 Then
SendEmail
Else
CreateNewSchedule
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
On Error Resume Next
Application.OnTime EarliestTime:=nextScheduledTime, Procedure:="macro_name", Schedule:=False
End Sub
You can then continue to use Excel between the scheduled times.
I think you need to specifically process the application event stack with a DoEvents call. This allows user interactions with the spreadsheet to occur, where normally the macro would take precedence. You code would look something like:
Do While True
If Value > 10 Then
SendEmail
End If
Sleep 60*CLng(1000)
DoEvents
Loop
You could also construct a GUI with HTA if you wanted to remain with VBScript.
I have found sources that say to use
Application.OnTime TimeValue("18:00:00"), "MyMacro"
But I can't seem to get it to work. This is what I have entered
Sub TimeStamp()
'
' TimeStamp Macro
'
' Keyboard Shortcut: Ctrl+Shift+T
'
Application.OnTime TimeValue("13:25:00"), "TimeStamp"
' Following refreshes the data
Application.CalculateFullRebuild
Then the rest of the code followed by End Sub
For whatever unknown reason, when I start the Macro, it does not wait until that given time. What syntax rules am I breaking here?
The macro is triggered when the macro is triggered. OnTime schedules it to be run automatically, but why should that prevent you from running it manually? Think of it like a virus scan. Many people have their computers configured to do automatic scans at certain set times, but are perfectly able to run nonscheduled scans at any time. If you want to make sure that your macro doesn't have any effect before a certain time, use an if - then statement involving Now (if it is too early exit sub) -- although it makes more sense to not run it at all when you don't want to.
Another method that I've used for years successfully is by just creating a small vb script that is scheduled to call the macro. My other answer to a very similar question show this example script
Dim xlApp
Dim xlWkb
Set xlApp = CreateObject("excel.application")
Set xlWkb = xlApp.Workbooks.Open("PATH TO YOUR FILE")
xlApp.Visible = True
xlWkb.RunAutoMacros 1 'enables macros to be run on open
xlApp.Run ("YOUR PROCEDURE")
xlApp.Workbooks("YOUR WORKBOOK NAME").Save 'Save the workbook
xlApp.Quit 'quits excel
Schedule this through Tasks Scheduler. My other answer can be found here
This is what I ended up with thanks to the help of several of you. I used:
Private Sub Workbook_Open()
Application.Wait "6:45:00"
Call TimeStamp
End Sub
and placed this in "ThisWorkbook". This made it so that when I open up my workbook, the macro is automatically started but it waits until 3:03 pm to perform the rest of the task.
Next, I needed it to refresh every 15 minutes so I used Chip's solution suggested by User: Findwindow. The code goes as follows
Public RunWhen As Double
Public Const cRunIntervalSeconds = 900 ' 15 minutes
Public Const cRunWhat = "TimeStamp" ' the name of the procedure to run
Sub StartTimer()
If Time < TimeSerial(13, 15, 0) Then
RunWhen = Now + TimeSerial(0, 0, cRunIntervalSeconds)
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, _
Schedule:=True
End If
End Sub
at the end of the TimeStamp macro, I put Call StartTimer so that every time the macro is ran, the timer will schedule a new run time for 15 minutes from the current time. The If Time < TimeSerial(13, 15, 0) Then allows for the macro to stop running at 1:15pm, the time that I wanted it to stop.
I've done a fair bit of research on here to try and get this code to run, but I'm still having issues.
I am trying to run a macro at a set time. In fact it is a number of macros as different times. This macro then copies a block of cells, into a different area on the sheet.
I will not be able to use windows scheduler so I'm trying to do it this way. I gather without scheduler I will have to run the macro from a button. Therefore, my first sub is this (note button is on a separate sheet to the data)
Sub Call_save()
Call Sheets("Dashboard").8amsave
Application.OnTime TimeValue("08:10:00"), "Call_8amsave"
Call 9amsave
Application.OnTime TimeValue("09:10:00"), "Call_9amsave"
Call 10amsave
Application.OnTime TimeValue("10:10:00"), "Call_10amsave"
End Sub
This button is designed to then run the subs at the predetermined time. The subs it calls are these:
Sub 8amsave()
Dim current_data As Variant
current_data = Worksheets("Dashboard").Range("S6:V22").Value
Worksheets("Dashboard").Range("B33:E49").Value = current_data
End Sub
Sub 9amsave()
Dim current_data As Variant
current_data = Worksheets("Dashboard").Range("S6:V22").Value
Worksheets("Dashboard").Range("B54:E70").Value = current_data
End Sub
Sub 10amsave()
Dim current_data As Variant
current_data = Worksheets("Dashboard").Range("S6:V22").Value
Worksheets("Dashboard").Range("B75:E91").Value = current_data
End Sub
Now, when I run the initial button it runs all the subs at once and copies the sells into the correct places, straight away. This isnt really an issue for me. However, at the predetermined time I get an error saying unable to run the macro... can't find it or sheet unable to run macros... or something of that ilk.
Is there anything blindingly obvious that i am missing? I have kind of been working this out as I go along so my VBA knowledge is fairly limited. A point in the right direction would be great.
Your OnTime statements also appear to be referencing procedure names which don't exist, i.e., Call_8amSave as opposed to 8amsave. Note also that procedure names cannot begin with numeric (e.g., 8amsave) and this code should not even compile, let alone execute.
Rename your procedures so that they match the calls in the OnTime statement, and are legally permissible procedure names, like: Sub Call_8amSave, etc.
Also, the OnTime property can only have one procedure at a time, so you can't set 3 future times, you have to set them sequentially. So, set the OnTime for the 9am save during the 8am procedure, etc.
Option Explicit
Sub Call_save()
Application.OnTime TimeValue("08:10:00"), "Call_8amsave"
End Sub
Sub Call_8amsave()
With Worksheets("Dashboard")
.Range("B33:E49").Value = .Range("S6:V22").Value
End With
Application.OnTime TimeValue("09:10:00"), "Call_9amsave"
End Sub
Sub Call_9amsave()
With Worksheets("Dashboard")
.Range("B54:E70").Value = .Range("S6:V22").Value
End With
Application.OnTime TimeValue("10:10:00"), "Call_10amsave"
End Sub
Sub Call_10amsave()
With Worksheets("Dashboard")
.Range("B75:E91").Value = .Range("S6:V22").Value
End With
End Sub