Revert MS Access file without backup - ms-access

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.

Related

Why does MS Access not allow to copy a file when it is being used?

Generally you can copy a file even though it is being used and paste it into a different location.
However, I am unable to copy an MS Access file when it is being used, I get an error that the file is being used by another process. Is there any way to copy an MS Access file that is being used?
Access files are shared database files.
That means, multiple users can write to and read from the same file at the same time, and Access has locks to prevent users writing things that other users are actively writing to, to prevent conflicts.
When a user starts writing, for example, by adding a row, but hasn't finished writing yet, it might leave the database in an inconsistent state (with half a row). This is a bit of a simplification, but with users actively using a database, corruption is certainly possible. It especially happens when Access needs to move stuff around, which happens when files are substantially extended (by adding tables, for example).
Other applications generally don't have multiple users working on a single file together, so can just write the data when someone saves/closes a file.
See this for some code that copies an open database file while not risking inconsistency.
Shadow copies can of course be used too, but you may very well end up with a corrupt copy.
You certainly can copy an open database file right away, but it has to be opened as shared.
However, if you open it exclusively, it cannot be copied, because Access locks the file.
You can rather split the database into the back end and front end
Give each user a copy of the front end
Then you can always copy your own copy of the front end and back end anytime
If you have any forms open that have a record source linked to a table, this will not allow the copy/paste

How do I prevent the access database from modifying and saving itself upon open?

When working with an Access .accdb, every time I open the file, I see that the 'date modified' in the filesystem changes to now. This makes me nervous. I want it to stop.
I can't be the only person who has ever saved a working db, and opened it a few weeks or months later to an error. Sure, I probably have backups, and backups to my backups, and table data saved separately from my code, and version history taking up multiple gigabytes of the filesystem or in emails or where ever... but it still makes my heart jump a little whenever I see the date modified update on open, when I haven't touched the DB in some time.
Have I flipped a switch somewhere that makes it do this? Is this expected behavior? How can I stop it?
To replicate this, create a new accdb, save and close. Put something in it, nothing, or close it only a second after creating it. Open an windows explorer for the directory the accdb is saved in, and note the date modified value. Open the file at least a minute after the displayed date modified file. alt-tab back to the explorer window, and you see the date modified has changed.
That's the default behaviour, even with a native Access MDB file. They don't work like a normal file that you have to explicitly modify to update the date - it does some things when you open it up, whether you want it to or not.
Just did a quick test - if you set the database file to read-only, it doesn't update itself.
I construct my MS Access Applications into front end and a back end. The Front end database is made up of all the the application objects like the Queries, Forms, Reports, and Modules. The back end database is made up of the tables and links to other data sources.
Many people consider this a Microsoft Access Generally Accepted Best Practice.
So much so that Microsoft includes a Wizard to do the split for you. Shown here
10 Reasons to Split an Access Database
Once the database has been split, It makes is a whole lot more manageable. The Front End can be marked read-only. The Back End remains writable.

Share a mdb file over network, for many computers, can't edit the application

The company is using an old Delphi software, that uses a .mdb file as database.
I can't change the way the application works, I don't have it's source.
We are facing many problems such as:
Lock problems
When an user adds an entry, it doesn't update the database, it only appears locally
The lock problems are solved for now, currently, the problem is that only the first user that connects to the .mdb can edit, add and delete entries, the other users do that to, but the changes are not applied to the db, it seems it's only apply locally, on the user machine.
My question is, is .mdb supposed to work with many users over the network(3~4 people)?
What Is there anything I can do to make this software works well with the .mdb file, with many users?
Remembering that I cannot split the .mdb, as I cannot edit the Delphi application.
You don’t mention that if this in the past work fine in a multi-user environment. However, keep in mind that users MUST have full read/write AND ALSO file create and delete rights.
The reason for the create and delete rights is that because this is a “file based” system without a server process, then a locking file is created in the same directory as the back end mdb file. When the first user opens the file, and they don’t have FULL RIGHTS to the folder, then the file is opened in exclusive mode, and all additional users will be read only. This thus explains your symptom of first user in, but additional users don’t work. (the additional users will be read only – and obviously the Delphi software does not detect this problem). So you can view data – but no saving of data can occur.
So you need to ensure that all users have the ability to create that locking file. It is created by the first user, and any additional user opening the back end ALSO needs rights to that file (so don’t by mistake have permissions to the folder set on a per user basic, since then the first user in will cause JET to create the locking file but with permissions to that first user!. Once again this will mean additional users will be read only. So additional user MUST be able to open the locking file, and the first user in MUST be able to create the locking file. In fact open Access will open the database (mdb) as exclusive and prevent multi-user when the locking file cannot be created.
When the last user leaves the database (or in your case leaves the Delphi application), then the back end file is closed and ALSO THE locking file is deleted by the database engine (JET)
So this sounds like your IT folks did not give wide open permissions to the back end folder. You “can” run the database with file delete rights removed, but I much suggest that the locking file being re-cycled is also a good thing since over time it can become damaged etc.
So based on your symptoms, this is a VERY common occurrence in Access, and this problem is fixed by giving all users sufficient permissions to create files in the same folder as the back end. (and not permissions based on per user).
ALL users must be able to create + open + use that locking file created by the first user opening the mdb file. This locking file creation is automatic and managed by the JET database and not the Delphi program.
Yes, it can work with x ppl on a network.
Make sure the Access database is set to open in shared mode, which is the default setting.
Tools menu, click Options.
On the Advanced tab, under Default open mode, click Shared.
Use this Powershell script:
Get-SmbOpenFile | Where-Object -Property ShareRelativePath -Match ".mdb" | Close-SmbOpenFile –Force

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.

Don't have exclusive access to database and so cannot save changes

I'm working on a MS Access database. I've made some changes to one of the modules. I want to go out for lunch, but when I try closing the database, I get the following message:
"You do not have exclusive access to the database. Your design changes cannot be saved at this time. Do you want to close without saving your changes?"
I'm pretty sure nobody else on the network has the database file open, and I don't have any other Access databases open. I'm probably missing something obvious, but would really appreciated some help!
Update:
In the end I copied all the code, closed the database without saving, re-opened it and pasted the code back in. I was then able to save the database. I'm not sure if this was a one off, but I'll report back if it happens again.
If you're sure no one else is in the db but you, it's an additional connection to your db from your own pc. You can verify this with the LDB viewer, downloadable in the free JetUtils.exe download from Microsoft:
http://support.microsoft.com/kb/176670
Look through your code and check if you have two separate database objects in the default workspace or another database object in a separate workspace. That will cause this problem.
To fix it, make sure the database objects are set to nothing before they go out of scope, and if you opened the database object in code, you also need to close it before setting the database object to nothing.
=============================================
Update in August 2022:
The MS link above no longer works. The document remains available on Archive.org, but is outdated. A document that appears to provide the current version of its information is at:
https://learn.microsoft.com/en-us/office/troubleshoot/access/determine-who-is-logged-on-to-database
This provides VBA code for a sub to obtain a list of users. The writer of this update has tested that code successfully in Access 2019.
If you close the database and are sure nobody else has it opened, check to see if there is a .ldb file (it will have the same name as your database file). If the file is there, then there is a good chance it is still in use.
Is it being access by a service, like a website?
You could copy the database to another sub-directory and make your changes. If that doesn't work, I will have to look that up. Of course there is always the database tool, "repair and compress database..."
Is the file located on a file server? If so check to see if any users have a file handle to it.
If it still doesn't work, update your post with your new information and we'll go further.
UPDATE (9/26):
Another thing I do when having strange issues with access databases with contain vba code is decompile. I don't know if this is documented yet, I haven't looked in years, but it's was (at least) an undocumented switch to msaccess.
From a cmd line:
change directory to where msaccess.exe is located.
Run the following command
msaccess \path to access file\databasefile.mdb /decompile
usually runs very quick then opens the database. Open any module and compile.
Doesn't always work, but sometimes can remove strange happenings.
Did you ever trying to copy the database to another directory and making your edits? That should of worked; you could then rename the original and copy the file back.
Anyway, I am glad you are working again.
If even a word mail merge is linked to the access database, that counts as an access connection.
Very simple.
Close all of your MSaccess files.
Open task manager (by right click on task bar).
Select Processes tab in that.
If the list has a msaccess*32 process close that by clicking on End Process.
This worked for me. I think it closes all the recordset which we have not closed in the codes or which is closed forcefully.