Pause Excel macro while Windows is locked - vba

I have a macro which runs an SQL query, which triggers a long slow recalculation of the spreadsheet based on the new data. When it finishes I've used application.speech to alert me if certain conditions have been met; all this works fine. But:
As I said, the recalculation can take quite a while, so I sometimes lock Windows and go do something else while I wait. Does anyone know of a way to pause the macro so that it doesn't run the last few lines (i.e. the audio alerts) until Windows is unlocked?

Before you call Application.speech you could check if the system is locked and if it is locked you repeat the check every minute until it is unlocked.
Code if a system is locked
Sub SystemLocked()
Do While Check_If_Locked = "Locked"
Application.Wait TimeValue("00:00:01")
Loop
MsgBox "Done"
End Sub
Code for Check_If_Locked can be found here
https://www.mrexcel.com/forum/microsoft-access/646623-check-if-system-locked-unlocked-using-vba.html

Related

Infinite Loop crashes VBA/Powershell and Win11

How can I create a Powershell or VBA script to run a command, wait and loop the command and wait infinitely until I close the respective window? I have tried the below in Powershell and VBA but they make the respective Powershell or VBA windows unresponsive and a bit later the whole system becomes unresponsive and I have to reboot.
Sub proc()
Do while $true
Application.Windows("workbook1.xls").Activate
Application.Wait(Now + TimeValue("0:10:00"))
Loop
End Sub
UPDATE:
I think it's obvious what I am trying to do: activate the window of a particular workbook every few seconds indefinitely.
I have tried DoEvents (both below the Application.Windows and the Application.Wait but it does not solve anything. Also I saw the below which says to avoid DoEvents:
https://www.fmsinc.com/microsoftaccess/modules/examples/AvoidDoEvents.asp
I tried Application.OnTime which made things much better but eventually got unresponsiveness too

Using Excel while macros are running

There are a half-dozen answers to this. "Open a second instance" "Have a pause" Etc. I'm not looking for that.
I'm looking for the user of the workbook to be able to manipulate the workbook while the macro is running. I've seen this working before, where the user could scroll around, change tabs, even add and remove data, all while the macro was running. Unfortunately, I couldn't get permission to look at the code (And committing CFAA violations ins't my cup of tea), so I have no idea how they did it.
How can you enable a user to edit the workbook as macros are running? For a specific example, I have Conway's Game of Life running. Users select cells to flip live/dead, then can run a macro to run the entire thing. I think it'd be nice for users to be able to change cells as the macro is running. (which is a second on select macro)
Thank you
Sorry just reread the question. I wouldn't expect the permutation to run for very long - not long enough to interrupt really.
But if it does, then the advice about using lots of DoEvents stands.
The other option is that you can use the OnTime event to have a "heartbeat"
VBA Macro On Timer style to run code every set number of seconds, i.e. 120 seconds
You can set the timer to say 3 seconds. Every time the OnTime event occurs you do one step of your permutation. In the three seconds in between they can edit.
Refactor your macro to use Events. In which case, you would have a series of event handlers (instead of one monolithic macro) to respond to various triggers. This is assuming that the macro is influenced by what the user is doing in the worksheet.
One way of (sort of) doing this is to use a Modeless Userform (UserForm.Show vbModeless)
The user form stays visible but the VBA stops running when the form is shown and the user can then interact with Excel. Then when the user clicks a button on the form the code behind the button starts running again.
So in reality the user is either interacting with Excel or interacting with the form ...

VBA to stop running nested macros in excel?

I have a button on my spreadsheet that when clicked, triggers a series of nested subs. Example:
Sub Button1_Click()
Macro1
Macro2
Macro3
Macro4
Macro5
Macro6
End Sub
Because the time to run all these subroutines can be rather lengthy, and the user cannot do anything else in excel while it is running, I was wondering if there was a way to create a button that, when clicked, can halt the running of all these subs? I've seen recommendations of adding DoEvent to the code, however, I'm not sure where in my code to implement it.
Any insight would be much appreciated.
The DoEvents statement will allow any lagging user input and handling of events.
The Solution
What you probably want to do is overload the OnKey event handler and use it to set the value of a global variable. Next in your code above you need to verify if that variable is set. If it is abort execution. Be sure to add DoEvents statements in any moments in your code where you want this to run.
Optionally, w/o the OnKey handler, DoEvents will allow the user to hit ESC to stop the execution of your macro. But it will revert to debug mode and highlight the current executed row in your procedure. Not sure this is what you want however.
Tip - what to do first
Having said that... what I personally think you should do FIRST is optimize your VBA code. I would assume there is probably a lot of room for improving the execution time of your procedure (my tutorial).
You can create Macro to perform below steps/operation and call when you want to abort the other running macros:
Step 1-- Menu bar -> Run -> Reset
Step 2-- Menu bar -> Run -> Break

Microsoft Excel 2013 ScreenUpdating fails

After running a macro for a prolonged period of time the ScreenUpdating in Excel totally stops working even when the macro finishes. I never set it to false but it behaves as if it is set to false and the only way to make Excel update the screen again is to close it out and reopen it. The VBA screen works however. I have tried to run DoEvents and ScreenUpdating=True but the Excel window does not update visually (it is not frozen). Is there anyway of clearing the ScreenUpdating buffer? I have tried manually setting it to false and true to no avail.
If you want to duplicate this error use this code
Application.OnTime (Now + TimeValue("0:00:05")), "macroName", (Now + TimeValue("0:00:10")), True
then I have the code copy and paste some values and I control when the loop stops with a countdown value in cell A1 for example.
I got this issue in my Excel 2013. For me, it was caused when I loaded a userform. It was very, very strange, however. After a lot of trial and error I found that what caused it was using a Sheets("MySheet").Activate command. I moved this command from running after I had shown and closed the form, to immeiately before I show the form (i.e., immediately when user clicks the 'show form' button.) This fixed it. Try fiddling with your sheets.activate commands.

SendKeys to click on a dialog box button in Access

I am using Access 2013. I searched a variety of online resources. I thought SendKeys was the answer.
Once per quarter, my client will receive an updated Access database. All table names should be identical each quarter. I want them to run a macro, specify the location of the new file, and then the macro updates the linked tables and executes all other queries I’ve built (I have the last part working).
The part I have not be able to get working is to check the “Always prompt for a new location box”, check the “select all” box and click OK (and then click OK and close after the client specifies the new file location). Below is the code I am using.
Function Open_LinkedTableManager()
DoCmd.RunCommand acCmdLinkedTableManager 'this step works fine
'the following lines, up until Application.Run don’t appear to be
'doing anything. The code will run, but I have to manually execute
'each of the steps I am trying to automate before it gets to the
'Application.Run step
SendKeys "%a", True ' also tried SendKeys "%(a)" and "+a", "a", etc,
'True; Alt+a checks the "Always prompt for a new location box”
SendKeys "%s", True ' also tried SendKeys "%(s)", True; Alt+s checks the "select all" 'box
SendKeys "{Enter}" ' then user specifies location of new file
SendKeys "{Enter}" ' click OK after receiving message "All selected linked tables 'were successfully refreshed"
' click Close to close linked table manager and proceed to the next step below (not 'sure how to do this)
Application.Run ("Update_all_queries") ' this is working;
End Sub
If sending to yourself then try DoEvents after each sendkey.
DoEvents Function
Yields execution so that the operating system can process other events.
Syntax
DoEvents( )
Remarks
The DoEvents function returns an Integer representing the number of open forms in stand-alone versions of Visual Basic, such as Visual Basic, Professional Edition. DoEvents returns zero in all other applications.
DoEvents passes control to the operating system. Control is returned after the operating system has finished processing the events in its queue and all keys in the SendKeys queue have been sent.
DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file. For long-running processes, yielding the processor is better accomplished by using a Timer or delegating the task to an ActiveX EXE component.. In the latter case, the task can continue completely independent of your application, and the operating system takes case of multitasking and time slicing.
Caution Any time you temporarily yield the processor within an event procedure, make sure the procedure is not executed again from a different part of your code before the first call returns; this could cause unpredictable results. In addition, do not use DoEvents if other applications could possibly interact with your procedure in unforeseen ways during the time you have yielded control.
I have solved your dilemma. All I needed to do was place the sendkey statements before the call to to the linked tabled manager. See Below - Worked Great For Me! I was also able to add all of the commands in your order and they worked great. Good luck, hope this helped. Let me know. Adam
PS: If you have many tables to change the path on, this will be painful for the user for every table you are forcing them to have to set the path for.
SendKeys "%s", 1
DoCmd.RunCommand acCmdLinkedTableManager