compact ms access database in vb.net without copy of the database - ms-access

I have searched the net on this topic and found, that if an ms access database should be compacted, then I should give the database itself and a new path.
Why is this necessary? If I check in ms access, that it should compact the database after closing, it don't creates a compacted database and deletes the old one, but it compacts only the one database. Or it is so fast, that I can't see it?

Access creates the compacted db as a new file, deletes the old (uncompacted) db file, and renames the new file to the old name.
It always works that way regardless of whether you compact from external code, from within an active Access session, or with compact on close at the end of an Access session.
With a small enough db file, the entire process can complete so quickly that you might not notice the transitional new db file. But with a large enough db file --- 1 GB should do it --- you can watch in Windows Explorer as the new db file is created and grows to it final (compacted) size.
Incidentally, be cautious about compact on close. Many experienced Access developers recommend against that option. The reason is that if anything goes wrong during compact, the new db can be corrupted and your original uncompacted version will be gone ... so no hope of recovery.

Related

Can't compact an access MDB

I have a client with a reaaally old MDB which we didn't make and they can't contact the guy who did it and recently it started showing the error:
Cannot open database “. It may not be a database
that your application recognizes, or the file may be corrupt.
Even when I try to export all the tables it just keep showing the same error and if I try to Compact and Repair I get the error that I don't have permission to do so. I have tried with every single user on the computer. If I restore the previous version all new data will be lost and will just happen again eventually as it doesn't let me compact either and even if I try creating a new database or table in another database, it doesn't let me import the data into it.
I can read all the tables but can't even copy that information. I'm at a loss of what to do and they asked me to have it for tomorrow.
I will be thankful for any tip you can give me for solving this error
Edit:
I have tried opening the file with a newer access to see if I can compact and it doesn't let me enter with any user even though the MDW is the same
I solved it! And this is how:
I noticed that the database was about 1'99GB which is almost the size limit of an access database so I just needed to Compact and Repair but it didn't let me because of permissions...
The database had another extra user which we didn't see before for any reason, that user was not even an admin, he was the real user who created the database (even though it kept telling me everywhere that the database was made by the admin and that he was the propietary...)
Since compacting gave me an error that couldn't find the database "Tempmsysaccessobjects", I just had to google it and found the solution in a spanish forum where they recommended creating a new database and importing all old data and with this user it let me do it!
Thank guys for helping!

Why do MS Access front-ends increase in size over time?

I have an MS Access front-end (Oracle back-end) that has 2 linked tables, 2 MS Access queries, and 4 reports.
I've noticed that the .accdb files (stored on users' desktops) get bigger over time. They start out at under 1mb after a compact, and end up being 10-20mb after a few months use.
Why is this? There isn't any data stored in the file, so why does it get bigger over time?
It's because (some) temporary data are created in the frontend. It shouldn't matter at all, except if it disturbs you.
You can avoid that completely by making the frontend file read-only, but usually it pops a warning message when the user launch the frontend. It will force temporary data to be written to separate files.
Another method is to set the frontend to compact before closure. However, that sometimes fail, thus causing more trouble than advantages.
The definitive method to avoid it, is to copy a fresh frontend to user. The user clicks a shortcut to a script that copies the file from the server to a local folder and launch it from the local copy. A script to handle that can be found here:
Deploy and update a Microsoft Access application in a Citrix environment
I had the same problem and this is what I learned :
Front-End file size can increase because of a lot or reason and it is important to verify what is the cause. (Memory Leak, Image Management etc)
A good deployment architecture is important and will help avoid the file to increase over time:
Good Example of deployment architecture
If it is too late and your file have already increased, you can normally return close to the original size with the "Compact and Repair Database" functionality:
Open Access in design mode
Access Section "Database Tools"
Select "Compact and Repair Database"

Microsoft Access Linked Table - Can I use an .accdr file as a backend

Can anyone confirm whether linking to tables in a Microsoft Access .accdr files is possible?
I have a split MS-ACCESS application with the frontend in a .accdr file and the tables in an .accdb file backend on a server. For reasons that I explain below, I need the frontend to connect to a table in a second backend file (also on the server) that has an .accdr extension.
I found no documentation that explicitly states that .accdr files are not allowed as as a backend database, however, the linked table manager does not seem to allow it, and the DoCmd.DatabaseTransfer method throws an error.
My workaround is to temporarily rename the .accdr server file as an .accdb, link to the tables in it to make the data changes, then rename it back to .accdr. But if I don't HAVE to do this, I would prefer to connect directly.
Reason:
To make sure that each client gets the most recently updated copy of the frontend .accdr, I created a batch script that first copies the frontend from the server to their local machine before launch. It's a short time penalty (the frontend is about 8 MB) each time they load the application, but the batch script makes sure that the client is ALWAYS up to date. (If performance became an issue I would of course have the batch script verify MD5 sums before downloading, but it hasn't come up yet.)
I don't have many clients connecting at the same time (only about 2 or 3 concurrent connections), but they can connect from any of thousands of computers on campus, so I found this the easiest way to make sure that no matter where they connect from, they will get a fresh copy of the FrontEnd.
Unfortunately, I made a few tables local to the frontend because they allow individual users to set parameters locally during a session. Now, of course, I have a case where an individual user needs to update these local tables so that all the other users will get this same data. (Previously, I had just been making these changes manually upon request, but this user quite reasonably needs to be able to do it herself.)
So, the local frontend .accdr file needs to connect to the server copy of the same frontend .accdr file to make a few data adjustments in a table. That's the reason. I know it's weird.
Thanks,
Damon
Turns out it is possible to use .accdr as a backend. I think i was specifying the wrong connection or something. I used this code snippet with the strConnect = path_to_mydb.accdr:
Public Sub ConnectOutput(dbsTemp As Database, _
strTable As String, strConnect As String, _
strSourceTable As String)
Dim tdfLinked As TableDef
' Create a new TableDef, set its Connect and
' SourceTableName properties based on the passed
' arguments, and append it to the TableDefs collection.
Set tdfLinked = dbsTemp.CreateTableDef(strTable)
tdfLinked.Connect = strConnect
tdfLinked.SourceTableName = strSourceTable
dbsTemp.TableDefs.Append tdfLinked
End Sub
You could easily add the tables that are local to your front-end to the backend. Just copy/paste them from one to the other, delete them from the front-end and link them to the backend version. Takes all of 5 minutes, no VBA code necessary.
Regarding the accdr as a backend question, then yes, accdr is meant to be a open by a the Runtime version of Access. Opening an .accdr file with the standard version of Access simulates the Runtime mode. The only difference between the standard version and the free Runtime version is that you can't access the design tools and the standard ribbon from a Runtime application (you need to create your own).
So renaming a accdb file into accdr only tells access to open the database in Runtime mode. It doesn't change the database itself at all.
So you can use an accdr file as a back-end without problem.
Pro tip: if you want your setup to scale a bit (easily up to 50 concurrent users) and have better performance, open a database to a dummy table from the front-end to the back-end. This will keep the connection open while the front-end is running and keep the lock file open on the database, resulting in better -and more reliable- performance.

How to wait for Compact Repair - Access VBA

Have a VBA Module in Access 2007 which performs similar actions in a For loop.
At the end of every loop I wish to compact and repair the current database before proceeding to the next iteration.
Reason : In every iteration I create , use for calculation and delete a table.
The size should remain under control.
Using SendKeys , I cannot compact and repair - if calling the module from a Form Button.
Any trick to ensure that the SendKey works fine and the Module continues onto the next iteration flawlessly. Some idea to control Form loading / Module execution / Checking Status etc.
End Purpose being to wait just long enough till the Compacting is done and then move on. Also how to safely ensure that SendKeys / (suggest alternate) for compacting works fine.
Thanks
"... in a For loop. At the end of every loop I wish to compact and repair the current database before proceeding to the next iteration."
Consider what actually happens when you compact the current database. Access first creates a compacted version of the current database as a new db file. Then it deletes the old db file, renames the new file to the old name, and finally opens the new db file.
So if your code attempted compact each cycle through a For loop ... when Access then opens the compacted db file ... how would it know you wanted it to continue in that For loop?
If you truly want to do something like that, you will have to store a value to record which was the last iteration of the For loop. Then create an autoexec macro to retrieve that value at database open, and enter the For loop at the appropriate cycle. And then decide whether you really want that all to happen every time the database is opened.
However that seems like too much effort to me. It should be simpler to use another db file to hold your volatile data. Then from code in the current database you can use DBEngine.CompactDatabase to compact the external db file.
If you're doing that much compact & repair, then I would split the DB into a front-end and a back-end. All your tables will be on the back-end. Splitting the DB is pretty standard for any regular Access programmer anyway.
Then when you want, use the Shell command to open the back-end DB with the /compact switch. This will open it, do a compact & repair, and then close it.
So, your code will be something like this:
Ret = Shell("C:\Program Files\Microsoft Office\Office12\MSACCESS.EXE /compact c:\MyFolder\MyDB.accdb")
If you need to wait for it to finish, then use the WScript.Shell command instead.
Good Luck
You cannot compact and repair the current database in a loop of any kind. You could compact and repair an external database in a loop, or you could compact the current database on close.
I've already answered your other question (which is quite similar), but for the sake of helping others I have published a simple utility function that helps you restart and compact the current database:
Restarting and compacting an MSAccess database programmatically
To ensure that you continue the proper iteration after you restart:
save the state of your operation (for instance the loop count) in a LocalSettings table (for instance) in your database.
Restart.
Use an autoexec macro to launch the function that does your work: it should load the operation/loop count from the LocalSettings table and carry-on.
Another solution is to modify the restart function to pass a custom command line argument to the Access application that you can check when the app restarts.
You can easily check for command line arguments, see the VBA Command function.

How can I programmatically repair (not merely compact) an Access .mdb file?

I have a corrupt database. If I open it in MS Access, MS Access offers to repair it, and it succeeds.
How can I do that with code? On a machine where MS Access is not installed.
I know from trying it that JRO.JetEngine.CompactDatabase does NOT work.
In other words, I want to do what Access or JETCOMP.exe is doing, not what JRO.JetEngine.CompactDatabase is doing.
You need to go to http://support.microsoft.com and search for the JetComp.exe utility, which will attempt to repair and compact your MDB without opening the file. The reason none of the suggestions above work is because they have to open the MDB to do their work, whereas JetComp doesn't open the file, but operates on it structurally.
If it can't recover your file (which does happen), then you'll have to go to a data recovery service. I recommend Peter Miller of PKSolutions.com.
Command-line switch for opening a .mdb file:
/compact
It repairs and compacts the database file.
If you leave out a target file name following the /compact switch, the file is compacted to the original name and folder. To compact to a different name, specify a target file.
Have you tried DBEngine.RepairDatabase [my.mdb]? (which doesn't seem to work any more even when you reference an earlier version)
However, if is happening so often that you need to code it, you probably have a bigger problem you should be solving first.
If you are willing to use separate utility, how about the Jetcomp.exe utility (http://support.microsoft.com/kb/295334 ). It is supposed to "be able to recover some databases that the Microsoft Access compact utility and the CompactDatabase method cannot." In which case, all you need to do is execute the external application.
e.g.,
Call Shell("Jetcomp.exe <arguments>")
I'm not a MS Acccess guru, but it appears as though this utility contains the DLLs you'd need to compact and repair a corrupt database file.