MS Access: Restarting and compacting the database programmatically
Tuesday, May 6, 2008
In my previous article about changing the MS Access colour scheme I had the need to allow the user to restart the database after the colour scheme was changed.
(Article and Code Updated 13FEB2009.)
Being able to cleanly restart and compact the application is also useful in other instances:
- Changes made to the environment
- Recovering from errors (for instance after a network disconnection)
- Forcing the user to re-log cleanly into the application
- Automatically restarting a long-running application (for instance so that it may automatically compact on close and restart afresh with or without user intervention).
The problem is that you cannot -to the best of my knowledge- close and open again the same database from within MS Access itself.
Most executables cannot do that and the way to solve the issue is usually to pass the control to another boostrap programme, close the main application and let the bootstrap programme re-open the main application again.
I wanted a simple and clean way of using it. One that would not require shipping external programmes.
How to use it
Download the sample database below, copy the Utilities module or just the Restart sub defined in it into your own application.
To use it, just call the Restart sub and the application will close and re-open.
If you supply the optional Compact:=true parameter, the database will also be compacted during the restart process.
This will work for normal databases (mdb/accdb) and also compiled (mde/accde) and runtime (accdr) databases as well.
Important note
If you want to use this code do not enable the Compact on Close option in Access for your database as the code doesn’t pick that up yet.
Instead, you can either simply call restart Compact:=true on user action (for instance from a menu) or on other triggers, for instance when the database is being open and hasn’t been compacted for more than a week.
How it works
If you’re curious about the technical details, here is how it was put together.
The main idea is that the MS Access database application has to be self-sufficient and restart itself by performing these steps:
- create a small batch file
- run the batch file, passing the path and extension of our database
- close the main application
- the running batch file would wait for the MS Access lock file to be removed
- once the lock file disappears, we open the database after compacting it if required.
The key point here is that the batch file cannot just reopen the database right away: if the application is big or if it’s compacting on close for instance, it may take several seconds to actually close.
The only moment we can be pretty sure that the database is effectively closed is when the lock file is deleted by MS Access.
The batch file is hard-wired in the Restart sub that does all the work:
When the application runs the batch file, it passes 4 arguments:
- the full path to the MSAccess.exe executable (used for compacting the database)
- the full path to the database without the extension
- the database file extension without the leading “.”
- the appropriate database lock file extension (
laccdborldb).
This allows us to easily construct the path to either the database or the lock file at line 07 and 09.
Line 08 is actually only inserted if we need to compact the database: it simply launches MSAccess.exe with the /compact command line switch.
The funny use of PING is actually a simple way to wait for some time before we check if the lock file is still there or not. There is not SLEEP or WAIT function provided by default in Windows so we have to be a bit creative and use the time-out option of the PING command trying to ping an inexistent, but valid, IP address.
Once the lock file has disappeared, we open the database at line 09 and then delete the batch file itself so we leave no leftovers.
The other thing of note is that we now use a counter to keep track of the number of times we checked the existence of the lock file.
Once this counter reaches a pre-determined amount (60 by default, ~ 45 seconds) we consider that there is a problem and the database application didn’t close, so we just exit and delete the batch file.
Download the DatabaseRestart.zip (48KB) containing both an Access 2007 ACCDB and Access 2000 MDB test databases.
Other implementations
- Roger’s Access Library (MVP) has a different implementation on offer.
Code Updates
v1.2: 13FEB2009
- Added optional parameter to compact the database during restart.
v1.1: 09AUG2008
- Now a separate test database (used to be bundled with the Colour Scheme sample).
- Added support for older Access versions (an Access2000 MDB is now included).
- Corrected wrong lock file extension for accd* files.
- Added a time-out feature after which the batch file will delete itself after a while if the Access lock file wasn’t released (for instance following a crash).
- Added checks to delete the batch file if it has not deleted itself for some reason (for instance after a reboot).
- The batch file now has a unique name based on the name of the database, allowing multiple databases to be restarted from the same directory.
- Added license notice at top of source code.
- Updated the article to reflect the changes.
v1.0: 06MAY2008
- Original version

This work is licensed under a Creative Commons Attribution 3.0 Unported License.
Entry Filed under : Database, MSAccess, Programming, Web Design, sysadmin

16 Comments Add your own
1. Tony D'Ambra | August 6th, 2008 at 9:13 am
Compliments on your very elegant blog and code.
A couple of months back I tackled the issue of forcing a restart by calling a VB6 EXE on an Access UNLOAD event and passing the database file path as a command-line parameter. Now I can see your self-contained BAT file approach is better. I used WAIT to delay the restart, and then trapped the Unable to Unlock File error in a resume loop until Access unlocked the MDB file and deleted the LDB file. I was wondering why in your code, you try deleting the LDB file outside Access? Is there not a risk of corruption as the previous instance of Access would still exist until after its deletion of the LDB file?
2. Renaud | August 6th, 2008 at 10:38 am
Hi Tony,
thanks for your message.
Regarding the lock file, I assume that its deletion by Access is the last action performed once a database is closed, which would make sense since it’s the whole purpose of a lock file.
I do not attempt to delete the lock file, Access does that; the last sentence of the batch file, the
DEL %0actually deletes the batch file itself to keep things clean.Thank you again for dropping by.
3. Jacques | August 8th, 2008 at 8:53 pm
Nice, simple and clean.
A few comments:
1) I realise you work with Access 2007 (with new extensions) -- all previous versions use .mdb for the DB itself and .ldb for the lockfile -- by adding the ‘l’ in line 3, it doesn’t work for older versions (it should replace the ‘m’) -- any idea how to make it generic?
1a) Say you run a DB in execute-modus (extension = .accde) -- then looking for the ‘l’+'accde’-file is not going to work, as the lockfile will still be ‘.laccdb’ -- right?
2) When Access crashes, it doesn’t delete the lockfile -- in case you run this batchfile and the .ldb not being removed, you end up in an infinite loop -- not a resource-hog, I assume, but on creating this batchfile again (on restarting Access), you might run into trouble, as the previous batchfile is still present and you can’t create a new batchfile with the same name. Perhaps you should build in some timer that self-deletes the batch file (after 2 minutes). And give batchfiles an unique name (e.g. incl. a timestamp).
4. Renaud | August 9th, 2008 at 1:29 pm
@Jacques: you make some valid points and I have updated the article, the code and test database to reflect these improvements and corrections.
Thanks for the comments.
The test database for restarting the application is now available in Access2007 and Access2000 versions.
If someone could test the MDB version and let me know if it works properly or not I’d be grateful.
5. Lu Anne | August 13th, 2008 at 12:14 am
I am trying your restart function in Access 2003 -- if I don’t set the database to compact on close, the function works fiune. When I set the database to compact on close it never reopens the data abse. any suggestions?
Thanks, Lu
6. Renaud | August 13th, 2008 at 9:39 am
@Lu: it’s a good point. When access compacts on close it will take over its own restarting process and remove the database lock file.
In that case the batch file will assume that the database is closed and try to re-open it, which Access will not do since it is currently compacting.
I’ll see what can be done. My guess would be to try to detect whether the database is set to compact on close and find a way to detect when access has completed the compacting process.
7. Lu Anne | August 13th, 2008 at 10:25 pm
The above routine will detect if compact on close is selected. As for detecting when the database has actually closed, still working on that. I’ll keep you posted.
8. Jacques | September 5th, 2008 at 5:03 pm
@ Lu
It’s is not recommended to use ‘Auto Compact’ in shared environments\over networks etc. -- see this thread (which basically confirms my own findings): http://www.utteraccess.com/forums/showflat.php?Cat=&Number=603048&Main=601621
Compacting is a delicate process, which should be executed with ‘care’ -- only in a stable environment (local), making a backup first etc. (ok, I don’t always do that myself either, but we all should…).
So, compacting from code (http://www.mvps.org/access/general/gen0041.htm), you know when it is finished as it returns the result (http://msdn.microsoft.com/en-us/library/ms696119.aspx) -- after that you could use Renaud’s batch file to restart.
This thread contains some code to compact when your MDB reaches a certain size: http://www.tek-tips.com/viewthread.cfm?qid=642227
And here some sleeker code tha gives the user 3 options: http://forums.devarticles.com/microsoft-access-development-49/compact-database-via-vba-24958.html
I haven’t tested all the code, so don’t shoot the messenger…
9. bil643 | October 13th, 2008 at 11:07 pm
We don’t save data after inserting it in MS Access table. However when we open the table we observe that data is not vanished? Why?
Dear can u help me to solve this question? I hope to listen from you soon.
Thanks
10. Renaud | February 13th, 2009 at 12:22 pm
About Compacting: now the code offers you the option to compact the database during restart.
11. Andrew | April 17th, 2009 at 10:16 pm
Hi I am running your code in Access 2003 but in Access 2000 file format
I get the following error:
“Could not use ‘Z:\Project Metrics\Project Metrics -test.mdb’; file already in use”
I assume this is because it tries to open the database too quickly is this the case and if so can be further slowed down?
12. Renaud | April 21st, 2009 at 10:08 am
@Andrew,
could you send me your test database (see email at the bottom of the page).
Also, the code should only be used for a local database that is currently opened only once, not a shared one that could be opened by multiple users.
Thinks you can try:
Change the line that contains:
ping 0.0.0.255 -n 1 __-w 100__ > nultoping 0.0.0.255 -n 1 __-w 1500__ > nul13. Martin | September 11th, 2009 at 10:07 pm
Here’s a solution to make the excellent Restarter handle when Access is set to compact on exit. Works fine in Access XP (2002). No responsobilities taken.
Best regards Martin
14. Martin | September 11th, 2009 at 10:30 pm
or alternatively, you might not want to compact at this moment:
15. Naphta | October 7th, 2009 at 5:52 am
Hello,
It seems that it works as for self updating access frontend !
the first tests are good !
It’s great !!
Thanks
16. naphta | October 7th, 2009 at 10:33 pm
Hello,
All tests are fines !
I made test with an accdr connected by the network on a huge backend.
No problemo I give the code to a french forum.
Bye
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed