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

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.

Related

Revert MS Access file without backup

I was using an Access file a colleague of mine created. They run it without issue on their computer all the time, but when I tried running it on mine, without modifying it, I had a value prompt window come up that isn't supposed to.
I think there's some sort of auto save feature on this file because even after closing it without saving, this message shows up and I'm no longer able to run the macro within the Access file. This file is stored on a shared network drive and file history isn't enabled on this drive nor on my machine. I'm not too familiar with Access and my colleague is on leave for some time. No one else seems to know Access very well either. Is there a way than I can restore the file or the queries/macro inside it to how they were before I opened it?
The basic answer is No. If something really was changed, there is no automatic history that can be used to recover changed settings or macros.
I realize it doesn't help to say anything now, but I am very surprised if there are no backups for the shared network drive. Is there no IT personnel that can assist? Regardless of whether or not you can get the file working, I would immediately make your own manual backup of the Access database file(s). (As long as you have a backup... or even better multiple backups, Access files can simply be restored from the original using file copy and paste.)
"Autosave" is an understatement with Access, because unlike a word processing document or spreadsheet which can be held completely in memory, a database file is constantly updated. There is no in-memory context for the database file as a whole. Access will almost immediately update the file once it is opened, simply because it manages things like file locks, etc. The database may have an Autoexecute macro or other code that runs automatically, but this may be accompanied by security prompts, especially if you haven't opened it on that computer before. For standard forms, changes to data on a form are saved to disk immediately and no "Save" button is required. Certain aspects of the database file should not changed unless explicitly told to do so, and these are usually design aspects not change accidentally.

Read data from mde database

Ive got an mde file and all i need is to get data from tables of this file in any format... I've tried everything that I could find on the internet or get by myself, but nothing helps. When I am using standard tools for extracting data in access it says to me, that I have something running operations on that database( I think there is some kind of a macro or something else, that starts when I open this file).
If you have any info on how to get data from this file I will be SO thankfull!
Thaks again for your attention and I really sorry for my bad english(doing my best to learn speaking it better).
There are a few tricks you can try:
Press SHIFT when opening the file to disable autoExec macros.
Just in case the file is corrupted, try to compact and repair it (make a backup copy before!).
You can use the command line option /compact to perform the compact and repair without first opening the file.
You can create a new database and create linked tables from the other database.
You'll have the option of copying the whole tables (you may need to rename the .mde into .mdb so you can see it in the dialog asking for the file to link to).

What does Error 3112 indicate when compacting an MDB file?

What does Error 3112 indicate when compacting an MDB file?
The Error description is "Records can't be read; no read permission on 'xyz123.mdb'"
There is a known issue with the Compact function on some versions of Access MDBs. Is the solution in this case to run the Microsoft utility JETCOMP.EXE on this file?
What are the other possible causes of this error?
This could well be a sign of corruption, I would suggest that you treat it like that for now and try doing a compact/repair and also a decompile and see if that snaps it out of it.
This is of course assuming that you do have permissions on the database, you might also want to check which workgroup file you are “joined” to at the moment in case the above does not work
I can't say the error pertains to any one issue I can think of. It possbile that some other routine or part of the applicaton is open and not closed.
I assume this error is occurring for only one application ?
Try creating a blank database file, and then import everything into that file. Does the compact and repair now work? This sounds more like a damaged or currupted file.

external code file for microsoft access

i’m wondering if it’s possible to load code from an external file to be used in ms access. this is important to allow easy development using version control—.mdb files are impossible to version control.
See How do you use version control with Access development? for an excellent solution. I modified the vb scripts slightly to allow exporting and importing of queries, as well as the other types.
I use these scripts along with Mercurial to do my version control. Using Access 2002 this has been very reliable for me. I restored a previous changeset and rebuilt the MDB and it seemed to work with no problems. Also, remarkably few resources required. One of my projects has 12 changesets committed that take up a total of 16 MB in the repository, and the base mdb is about 10 MB itself. I highly recommend this approach.
You could write a small import/export tool (in the app itself, or in a separate MDB) which uses the Application.SaveAsText and Application.LoadFromText methods. These are undocumented, but once you've typed the method name into the editor it will prompt you with the argument types, which are: ObjectType As AcObjectType, ObjectName As String, FileName As String.
You might want to consider library database, i.e., and external MDB or MDE that has code that can be used in any MDB/MDE. If you're using an MDE for the front end, then it will have to be recompiled each time the library changes, which can be a real pain if you're trying to use a shared library MDE. This can be done with references, or by Application.Run, the same way you can call functions in the Access wizard database, e.g., the Zoom box:
Application.Run("UTILITY.BuilderZoom", "MyForm", "MyControl", "Values")
This is how you can launch the "zoom box" that you get in the Access UI when you hit Shift-F2 while in a textbox.
What it's doing is running the BuilderZoom function in the UTILITY database. There is no path specified because it's in the Access folder. If you have your library elsewhere, you'd have to supply the path to Application.Run.

How can I open an Access DB via ADO so that I can write, but others can only read?

From the documentation, I would expect adModeShareDenyWrite to be the way, but it's not working right.
I'm using an Access database via ADO. My connection string says Mode=8, which is adModeShareDenyWrite. But when I try to delete a row from a table, I get:
Unspecified error, Description:Could not delete from specified tables., Source:Microsoft JET Database Engine
In other words, the setting is preventing ME from updating the database using my OWN connection.
I found a couple other posts on the web reporting the same thing, the adModeShareDenyWrite setting used with Access not working as documented.
I am looking for a solution that doesn't involve an administrator changing permissions. It needs to be something that my program can control.
My motivation here is to minimize the chances of database corruption. One of the causes of mdb file corruption documented by Microsoft is two apps writing to the same db. So, I want to make sure that only one app can have a write connection to the db. Others can read, but should fail when they try to write. Whoever makes a connection first wins.
Cory Trager wrote:
My motivation here is to minimize the
chances of database corruption. One of
the causes of mdb file corruption
documented by Microsoft is two apps
writing to the same db. So, I want to
make sure that only one app can have a
write connection to the db. Others can
read, but should fail when they try to
write. Whoever makes a connection
first wins.
Why are you worrying about it? Jet is by default a multi-user database engine. If somebody else is updating a table, the data pages involved will be locked as read-only (in the state they were before the write began).
There is no realistic reason to fear corruption from mere multi-user interaction. Corruption of Jet databases usually happens because of dropped connections or an interruption of the connection during a write (such as users who force quit an app that is not responding as fast as they want).
I think your fear of corruption is misplaced.
On the other hand, you should still be able to open with an exclusive lock, and I'm not sure why it's not working. Have you considered using DAO instead of ADO to manipulate Jet data? Given that it's the native data interface (instead of a generic interface layer), it ought to be easier.
One solution is to give them access to a copy of the database. They can change whatever they want, but it won't keep past your copying it over with the master.
I suppose you access here an MDB file from a client interface, whatever it is, and others can also connect to the same file at the same time. When you use adModeShareDenyWrite in your connection mode, it means that you can still share the data with others (no locks of any kind on tables or records in the MDB file) but it can't be modified (this is why you get an error).
One solution would be to manage your connection parameters, with something like that:
(where you have a user object with a '.role' property, or anything equivalent ...)
if activeUser.role = "admin" then
m_connectionMode = adModeWrite
else
m_connectionMode = adModeShareDenyWrite
endif
Then you can open your ADO connection with the parameter m_connectionMode. Administrators will be given the right to insert/update/delete while other users will ony be able to view the data. This means you have somewhere in your program, or ideally in a table, some data saying who is what in your application.
EDIT: Following multiples comments with Corey:
You won't be able to do what you want to do in a straight way. My proposal: when the app accesses the database, it checks for a special file in the .mdb folder (whatever the file is).
If this file exists, the app opens a "read-only" connection.
If this file does not exist, the app creates the file (you can create one for example with "transferDatabase") and open a read-write connection. Once you quit the app, destroy the file.
If you have multiple users connecting to an access database across a network you might want to consider upgrading to SqlServer instead of using Access.
Corey Trager wrote:
I am looking for a solution that
doesn't involve an administrator
changing permissions. It needs to be
something that my program can control.
Well, if the problem is due to NTFS permissions being read-only for the user, there isn't a thing you can do to make the MDB writable. You don't specify where the MDB is stored, on a server or on a local hard drive, but in either case, for a user to have WRITE permissions on the MDB, NTFS permissions have to be set to allow it (for a share on a server, it has to be allowed both on the SHARE and on the underlying file). If it's a local file, the best solution is to make sure that you're storing the file in a location in which user-level logons have full WRITE permission. This would be anywhere in the user profile, and just about nowhere else.
That said, I'm not really suggesting that this is the source of your problem (I really can't say one way or the other), just pointing out that if it is the cause, then there's not a damned thing you can do programmatically to work around it.