Excel Code Blocking other Excel Sheets from opening - vba

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.

Related

Prevent >1 person from running VBA macro at a time (shared wkb)

What I'm aiming at is getting a list of all currently running scripts in order to check if other users aren't running the same VBA macro at the same time (and if yes, then stop the code etc., similar to what the OP of the below question wanted). This would be for a shared workbook (I learned it's not designed for this type of work, but I need to try it).
https://stackoverflow.com/a/36116091/5947935
I've been trying to make the code in the above answer work in VBA, but it seems it's a vbs thing and I would like to avoid that.
I'm not an expert to say the least, so I'm having trouble understanding how to get this to work in Excel VBA. I don't even know if it's possible at all.
I've found this as well: VBA Getting program names and task ID of running processes and it works fine but it only lists the running processes.
I've no idea however how to merge the two... or even if the WMI is the correct way to go.
I'd appreciate any sort of help.
I used to create a "locking file" which was just an empty text file with the name of the workbook followed by the username and an extension of .LCK
First thing my code did on auto open was look for a locking file then report back to the user which user had it open then cancel the open.
If it didn't find a locking file then it created one and proceeded as normal. If it found one but it was the same username (ie that user had it crash on them) it proceeded with the open.
The last thing the code did was delete the file.
No codes here and theory not tested yet, but the idea of preventing a different user executing a Macro on a shared workbook requires some thinking.
I would create a hidden worksheet, and use one of the cells to store the Environ("USERNAME") when the macro is first started - to indicate who has it running, then clear it when complete, first-in-first-out.
Lets say named range MUser (macro user) is range A1 in that hidden worksheet
When the macro runs, it will first check if MUser is empty, if so then change it's value to Environ("USERNAME") and Save the file before next step (here I am not certain the value is updated on others session).
If MUser is not empty, either abort or retry in a few second.
When macro completes, MUser will be ClearContents, and save the File to free up the workbook for macro.
Idea is here but please test. Post your own code for us to troubleshoot. You may also use Workbook events to "lock" the macro execution this way. Or even use this hidden sheet to make a log record for debug. Also some fail-safe needs to be implemented (such as a time stamp at macro start and override the lock after some minutes).

How to compact the VBA-project in an Excel workbook

I'm am searching for a way to compact the VBA project in an Excel workbook.
I recently discovered that the VBA project in one of my workbooks had grown over 60 Mb when I opened the workbook with WinZip.
The compressed workbook (.xlsm) exceeded the 10Mb limit that my email provider has set for email attachments. I had to take action or find another way to distribute.
I was able to reduce the size from more than 10Mb to less than 2Mb but that was a lot of work and I'm not certain if we can automate this.
This is the procedure I followed:
Export the code behind all sheets, ThisWorkbook, Forms, CodeModules and ClassModules.
Save the workbook as .xlsx (All code is removed)
Reopen the workbook and save as .xlsm
Import all modules again and past the code behind the sheets.
Now that I know that the VBA project grows without an option in Excel to compact it with a single press of a button, at least not an option that I know of. I would like to create some tool to do this every time I am to distribute the file.
Any ideas how the do this?
I have had good experiences with this tool:
VBA Decompiler

Excel workbook with macros using 50% CPU even when idle

First:
Using excel 2010, Win 7
All additional add-ons have been disabled
All spreadsheets have had the last used cell reduced to its minimum row, column value
I have an old machine in today's standards, Dell Inspiron 6400, 1.73 GHz, 3.3 Gig ram
I have a spreadsheet that when open and active it uses at least 50% of the cpu even when idle. If I then run other programs this has caused the computer to over heat and shut down. I posted this problem on a different forum a few months ago and the end advice was, "Don't worry about it". Well, I can no longer do this. It's become a problem.
At first I thought it was any workbook with macros. I have since convinced myself this is not the case. I then thought it might be add-ons that I have add. This isn't the case either. I read to minimize the spreadsheets to their smallest size. This didn't help. This workbook has an auto-open which saves a backup, gathers some data off the internet and does some manipulations with that data. I totally removed this subroutine, and no effect. Another thing to note is if I open another workbook, leaving this open too, and make this second workbook the active workbook, te cpu usage goes to nearly zero. One last thing to note is I have several precursors to this "final version" of this workbook. They all do not have this cpu problem. Somewhere, somehow, I have added some code to this "final version" that is causing this problem.
I'm hoping someone can give me some clues as to what else to look for. I will be comparing these old backups to the current version, but this is going to be the long way around. Any advice would be greatly appreciated.
Subject to my earlirt comment, when the Auto_Open macro ran everytime the workbook was opened, it created a new connection to its Internet data without discarding previous ones. These ancient connection should be listed Data ► Connections ► Connections and/or Data ► Get External Data ► Existing Connections.
As I do not have the full method and parameters of the internet connection created, I'll offer this sort `` event macro that will remove all connections whenever the workbook is closed.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
With ThisWorkbook
Dim cn As Object
For Each cn In .Connections
cn.Delete
Next cn
.Save
End With
End Sub
That macro goes into the ThisWorkbook code sheet. Note that it also saves your workbook; if this is not wanted behavior, move the code to a Module sheet and change it to a public macro that can be manually run.

Continuous Loop/Repeat causes Excel to Crash (after hours/days)

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).

Can you schedule periodic data imports in VBA?

I have a VBA function that, when invoked via a button on a sheet, extracts a .csv file from a website and imports it into my workbook. The problem is the file is uploaded in different time intervals during the day, so I have to periodically check the website.
Is there a way in VBA that I can schedule when a function is invoked?
You can use the Application.OnTime() method which will allow you to schedule a Macro for a specific time amongst other settings. However you're probably best using VB Script or similar.
It's also important to note that the workbook would need to be open the entire time if you are going to use VBA, whereas a VBS file will run silently and can be triggered to run at startup.
If you're proficient enough with VBA then you shouldn't have a problem writing VBS.