I have some VBA code that runs every 15 minutes continually. This code runs fine at first but after a period of time (which varies from around 4 hours to 5 days) Excel crashes.
It is not a VBA crash (with debug option) but it is Excel freezing and saying the application needs to be restarted.
Am I trying to use Excel in a way it was not designed for? Should I be clearing some memory/cache to avoid this?
I believe it is due to a fail of the OnTime method of the application, I had your same problem some time ago with an Excel tool which was scraping data from the web every 5 minutes. Sometimes it just crashed with no specific log or error/warning. Here is the workaround I have implemented:
1) In the Workbook_Open event I have put :
myMacro 'the call to my procedure when the workbook is opened
ThisWorkbook.Save 'I was saving the results, I don't know if you need this
ThisWorkbook.Close 'I was closing my Workbook
2) In the Windows system, I was using a tool (installed usually with the system) called Task Scheduler, whose executable lies into the system folder (C:\Windows\System32\taskschd.msc) and it's really intuitive and easy-to-use. I have scheduled a task every 5 minutes which consisted on opening the workbook (once this was done, the open-workbook-event macro was triggered so my procedure was called, and after its execution the Workbook was closed and saved with the two lines of code I have posted you above).
Even if this is just my opinion (that I cannot prove with technical evidences), I don't trust too much the Application.OnTime in the long-term; it works fine for a little task every 10 seconds for a few minutes, but when the macro should be running regularly and you want to avoid seeing that, once every 5 hours, the Excel process crashes... then I would suggest to let the scheduling task to the Microsot tool rather than to the Excel application method.
MY EXPERIENCE
- my Excel, with the OnTime method in the macro, was crashing in a period between 1 hour (minimum crash) and 7 hours (maximum length of time before crashing). I was forced to open a distance connection from home and running it in the morning before to go out, to make sure the job was done before I got at work.
- my same macro, with the procedure I have described you above, never crashed anymore. I believe the system process is much more reliable than the Excel's one (but again, I don't have any evidence to prove you this so don't take it as gold).
Related
I hope that you can help me.
That's my situation: daily I'm importing in Power Pivot some data through a query on a SQL database.
Actually every morning I open the Power Pivot and I refresh it for import the data of the previous day present in the database.
This action require 20 minutes because I have a lot of data to import.
I was wondering if there is a way to do this action during the night, maybe an automatic refresh, so that I can open the file in the morning and I alredy have the data of the previous day.
I hope that I was clear with my request, thanks in advice.
If the Excel workbook is on a machine that does not shut down, you can keep the workbook open and configure the query to automatically refresh ever x minutes.
Or you can keep the workbook open and run VBA code to refresh the query on a timer.
There are plenty of examples for VBA timers if you just care to search.
Or you can configure the queries to refresh automatically when the file is opened, then create a Windows Task Scheduler job to open the workbook at a specific time. Again, the computer running this must be turned on.
You see that there are many options and they are all well documented and just a short google search away.
I'm looking for advice on how to avoid Excel not responding during a long SQL query.
If I run my VBA code with the data already in place, the execution takes less than one second. When running the code with the SQL query, execution time jumps up to about 11 seconds, which is the same amount of time it takes for the query to run in Microsofts SQL Server Management Studio.
While the code finishes without further problems every time, Excel turns unresponsive after about 6 seconds, showing a blank screen and a "Not responding" text. ScreenUpdating, Calculation, and Events are all disabled.
The user doesn't need to see anything happening while the macro is running, but I'd rather not have my colleagues see a blank screen with the "Not responding" text every time they run the macro.
Any general advice or reading on how to fix this?
My Excel file blocks other Excels files from opening.
I have the below code
Public Sub Workbook_Open()
Application.OnTime Now + TimeValue("00:00:03"), "CommonWorkBook.prepareSheets"
End Sub
In PrepareSheets Macro, I take data from a txt file every 60 seconds.
The code is as follows
Do While 1 = 1
' Do Something
pause 60
Loop
After opening my .xlsm file, I am unable to open other .xlsm files.
If I close my .xlsm file, other files gets opened.
The problem is that when Pause is running it is still running. If you look in the task manager while pause 60 is being executed then you will see that it is using up almost all CPU from one of your cores:
Even if you could fix it -- do you really want to hog so much of your system's resources?
VBA is old technology -- only minor changes since the late 1990s. It is single-threaded. Only one single-threaded instance of the interpreter for each instance of the Excel application. The running code is what is preventing another macro-enabled workbook from opening.
There really is no easy way to do multithreading in Excel (but see this question). You should look instead for a solution involving Application.OnTime. Don't pause for 60 seconds -- schedule for 60 seconds in the future. See this (as suggested by #Ralph) for more details.
This question already has answers here:
Multi-threading in VBA
(8 answers)
Closed 6 years ago.
How can you switch between processes based on time?
++++
I have an Excel macro sending XML requests to Google, it has 3 important processes.
The process sending the XML requests. This process is limited to 10 requests per second.
A loading bar with the ability to quit the program
The Excel Application itself (it should be editable while the program is running)
The macro is currently using the sleep function (from kernel32.dll) to delay the processes, and the DoEvents function to make sure both process are run (and so the application can be modified in the background).
Ex. Process 1
Do While True
Call doSomething
DoEvents 'handles processes 2 and 3
Sleep 100
Loop
This method delays the entire application. Editing the Excel Worksheet in the background is laggy because of the 100ms delay, and attempting to quit the program is also delayed.
To remove this lag, I would like processes 2 and 3 to be running and switch control to process 1 when it is time to send a request. After the request is sent, process 1 can give control of the program back to processes 2 and 3. Does anyone have a solution to this?
Bonus: VBA seems to have little capability for multi threading/processing, but if anyone can think of a way to run all these processes at once I'd love to know about it
The implementation details are quite involved for each of the things you are looking for but they can be easily found by searching. So I'll suggest an approach for each of your questions.
Use Application.OnTime to trigger a macro to run after a given time interval.
Multiple threads can be executed, but it's tricky. You'll need to either
Invoke another instance of Excel and make it run your Macro, that way your main thread is not affected or
Put your macro into a separate text file (vb-script file) and call get it executed via Shell. That way you can continue executing the existing Macro and the user regains control of the UI, but the script fetches new data in the background.
Execute part of your code in a separate instance of Excel and then pump in the results into your current spreadsheet via DDE (older but fairly reliable technology) or by building something called an RTD server.
Ample examples of each of the above points are available on this site and elsewhere through Google.
I've created a small application that basically reads and writes to a single Excel.exe process. It's basically a timer that records the time I use on projects and then store it in an Excel sheet. This works great, however, I've noticed that if I open Excel manually, work on some sheets and whatnot, save and exit etcetc, the process my software use gets broken or something. The same thing that happens if I manually close the excel.exe process and my software doesn't "know".
So I was wondering if it's possible to protect the excel.exe process somehow? To make sure it can't be closed or tampered with in the meantime?
Let me suggest an alternative approach that does not require you to have an Excel process running all the time (after all, this also consumes a lot of system resources):
Let your application record your information. Every now and then -- for example, after a work entry has been finished or a specific time has elapsed -- open the Excel sheet, write the data, and close it again (also closing the Excel process that you are automating). This save operation should not take more than a few seconds and it will (mostly) prevent the problem you are experiencing.
In fact, since Office automation is always a bit painful, an even better way would be to output your data without requiring an Excel process. To do this, you could use
one of the third-party Excel libraries available for .net,
a CSV or HTML file, which can be opened by Excel, or
open the Excel file as a database with ADO.NET.
You cannot protect a process, but you can check the process.HasExited property to find out whether the process has terminated and take action based on that.
Add an exception handler. Either call non-throw methods if possible.