Microsoft Access: running "safe" mode (i.e. allow changes to be reverted) - ms-access

I'm using Microsoft Access as a means of managing data (that used to be stored in spreadsheets) in a more tabular, orderly, and logical manner. Everything seems to be working good for my client, but she has one question: "Is there a mode that allows changes to be reverted? Let's say I've made some changes, and I'd like to revert to my original version, is that possible?"
I understand her concerns and as much as I'd like to say "this is how a database works; you make changes to a row and they are written to the row immediately", I can't bring myself to say it. She's been using MS Excel and Excel has the ability of undoing multiple changes, as well as reverting back to the original file if you haven't saved it. To me, I feel that she is afraid that Access will bring about disastrous consequences--one fine day she's a bit groggy and starts making random changes all over, and then she has no means of getting back the original file. Bam.
What I'm asking now is this: is there any way/setting to allow Access to not commit changes immediately, perhaps until the user has clicked some button or something? It's not the way Access works, and please don't ask me to return to good old Excel because I enjoy and appreciate the chill WYSIWYG interface of Access and its familiar database environment. Maybe just not this behaviour, which came along with the databases.

If you are looking for a simple setting to preserve history, or enable undoing or force all changes to be encapsulated in explicit transactions, then you are out of luck as Access provides none of these out of the box.
There are however ways to implement all of these features to varying degrees, from a simple confirmation whenever the records are about to be changed, to create logs of all changes (so that the user can at least see what changed), to duplicating records before they are modified, etc.
Undoing an action can be something simple, like restoring a value you just typed, but it can become very hairy quickly if you want to undo an action that created or modified a dozen other records elsewhere in the database.
It becomes especially difficult if other actions have been performed after that one (by other users connected to the database for instance).
However, a few of things that could help you:
You can track all changes in a form and keep a log of the actions (in another table or just a text file):
Track all changes made to a record in Microsoft Access
KB197592:How to create an audit trail of record changes in a form
Creating an Audit Log
Add an Audit Trail to your database
you can use Access 2010 data macros to automatically trigger some action (like duplicating a record or keeping track of changes) whenever something is updated or added to the database.
Data Macro similar to triggers
Leveraging Data Macros in Access
you can use all forms in unbound mode and manually set the data when the form opens (or change record) and only save it back to the database when the user is completed.
All of these methods require work and testing and need to be adapted to the experience you wish to provide your user.
Another thing you can do is simply make copies of the database as backups at regular intervals, that way, if something goes awry, you haven't lost everything (this is mandatory anyway, I always have at least a daily backup system).

Related

Access: Record Locks - Edited Record property not working correctly

I'm fairly new to Access and am struggling with setting a pessimistic Record Locks policy (Edited Record). I have a database that I am developing and have not published yet, so it is not split at the moment but will be in its final form. I have a few tables that will be accessed through forms by multiple users at the same time, and ideally I would want the Record Locks property of these forms to be set as Edited Record on a row basis so that once a user starts editing one record, other users cannot mess with it but can still edit all the other records. I have:
set the relevant forms' Record Locks property as Edited Record
enabled the "Open Databases by using record-level locking" advanced option
read/write permissions to the folder where the database is
..but it is not working correctly. It seems that Access is still locking records at the page level, as I am prevented from simultaneously editing two adjacent or "close" (within 30 rows of each other or so) records.
I even tried creating a brand new database, just one table and two forms (actually one form duplicated with two different names) - result is the same, once I start editing one row of data in one form, all "nearby" rows are locked from editing as well. I tried splitting the database, asked another user to try on his machine together with me, but always the same result. What am I possibly getting wrong?
I have no issue sharing the brand new database I made as a test if needed, not sure where I can upload it though.
Ok, a few things:
Given this is not split? Ok, less things to check.
so, you have this setting:
and for the test form in question, you have this:
Now, we assume you not left out some huge-massive whopper here, right?
First up - we assume no one else, or no other program has this file open.
we assume that you do NOT have ANY startup code at all - but are just launching to that form? Right (if you have startup code - especially ANY code that opens the database or opens a table? ALL BETS ARE OFF!
next up: since this is a single user machine - I would re-boot - just to ensure that no stray copes of Access are running or were left running due to all this testing.
Note that the FORM MUST open the table(s) in question. There is NOT to be ANY code of ANY kind that runs before the Access UI application say via form OPENS that table.
The above is BEYOND important!!!
Why?
Because DAO code, VB code or ANY OTHER PROGRAM or PROCESS that opens the file BEFORE YOUR access applicaton does? Then you not get row locking.
And the above tip ALSO includes ANY VBA + DAO code!!!
You see, the JET (now ACE) row locking feature? There is ONLY one way and ONE WAY ALONE to use this feature:
It ONLY works from the MS-Access UI. That means no VBA code can do this, no vb.net code or ANY OTHER system or code can run before Access UI (forms) opens a single table.
The reason why?
The first person + process WILL determine if the row locking feature is turned on. And I want to double, tripe, quadruple and MORE stress that ONLY the UI can cause the ACE/JET data engine to engage this row locking feature.
In other words:
If on application startup ANY CODE that runs that opens a table (DAO or ADO code) then that code who FIRST opens the database will from that point on force ALL OTHER programs, forms and yes even MS-Access forms to NOT USE row locking. (you get page locking).
So, this is a first in kind of setting.
the FIRST process that causes a table to open will then determine if row locking is to be turned on. And the ONLY POSSBILE WAY for this to occur is if the MS-Access UI opens a table (any table) with a form. You cannot have ANY code run that touches a table BEFORE that UI opens a table. So any kind of say startup code, or even code (rather common) to create a persistent connection will thus ignore the row locking feature.
And if any other outside program, say ODBC from FoxPro, or even code in vb.net, c# etc. opens the database BEFORE the Access UI gets it hands on the table(s)? Then once again, row locking is not used (page locking of course will be used).
So the flip, the flag, the switch to row locking CAN NOT BE set in code. (you can set the options in access via code - but then you get that prompt about having to restart access (and you must do so if you change that row lock feature). So, code can change the setting, but it will NEVER take effect until you re-start. And thus once again, code cannot set this on startup (only change the settings that tells access what to do on startup - and it too late to thus change it in code once code starts running.
So, just keep in mind that you need as the first thing to launch is some form that is bound to a table, and that form will have to run first before any DAO or any other kind of VBA code grabs or opens a table via DAO or ADO code.
If code uses the DAO/ADO object model, then you by-passing the Access UI and thus no means to tell JET/ACE to use row locking. This is a MS-Access feature and NOT a JET/ACE data engine feature. As a result, you have to ensure that it is the Access UI that opens that table. Once that has occurred, then any and all other code, forms and even external ODBC connections will now respect the row locking feature.

How to manage "releases" with MS Access

I have an MS Access 2016 application that a few people use in one department. I know this whole thing has web dev written all over it but this access database has been their process for a while and there is no time right now to switch over.
Recently, a different department wants to use this application, but having their own copy. Currently, if I need to make changes, I'll make the changes in a copy of the app, they send me a current version when I'm ready to import their data, I import it and send them back a new one. However, currently I copy the data table by table and past it into the new database. This is inefficient and tedious, and now with 2 sets of data I'd be doing this for, that's crazy. There's over 20 tables so I don't want to have to manually copy over 40+ tables across the 2 apps for even the smallest change like altering a message to the user.
I know I can copy the code so I can avoid importing the data, but sometimes for big changes I'll change over 15-20 vba files.
So, a couple questions:
1.Is there a way to generate insert statements for the entire database that I could run in a script? So when I create the new copy I just upload 1 file and it populates all the data?
2.Are there any kind of dev tools that will help this process? Right now I'm thinking that it's just a downfall of creating an MS Access app, but there must be some way that people have made the "new release" process easier. My current system seems flawed and I'm looking to have a more stable process.
EDIT:
Currently I have all my data stored locally, attached to the same access file as the front end. Since I will have 2 different departments using the same functionality, how do I manage the data/the front-end? These 2 departments should have their own access file to enter data using the forms, so having 1 front end between the 2 departments won't work.
Also, should I create 2 separate back-ends? Currently I would have nothing to distinguish what is being inserted/changed/deleted from one department from the other. If I were to attach a field specifying who entered the record, that would require a complete overall of all my queries which I don't have the time for as there are deadlines I need to meet.
First thing is to split the database. There is a wizard for this.
Then you can maintain the frontend without touching the real data.
Next, consider using a script to distribute revised versions of the frontend. I once wrote an article on one proven method to handle this:
Deploy and update a Microsoft Access application in a Citrix environment

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.

Disable file autosave in Access 2013

There are two cases where Access autosaves changes:
When the user enters data into a form, this data is autosaved to the linked table
When the form developer modifies a query, form design view, table definition, etc. these changes are autosaved after exiting the editor
I'd like to know how to change the second point so that Access only saves the file if I hit CTRL+S, similar to Word and Excel.
Though Access does ask if I want to save changes when I exit (for example) the form design view, the only way to test changes is to exit design view, which saves the file and clears the undo button. It can be very inconvenient because I have to undo everything manually if I want to revert changes.
I've found threads discussing older versions of Access, but nothing for Access 2013. Is there a way to do this?
Forms, Reports, and Queries can be tested without saving - just switch view.
Tables cannot. If you wish to check out design changes, first create a backup of the database or at least the table.

How to set up a development environment in MS Access

I have created an MS Access 2003 application, set up as a split front-end/back-end configuration, with a user group of about five people. The front end .mdb sits on a network file server, and it contains all the queries, forms, reports, and VBA code, plus links to all the tables in the back end .mdb and some links to ODBC data sources like an AS/400. The back end sits on the same network file server, and it just has the table data in it.
This was working well until I "went live" and my handful of users started coming up with enhancement requests, bug reports, etc. I have been rolling out new code by developing/testing in my own copy of the front-end .mdb in another network folder (which is linked to the same back-end .mdb), then posting my completed file in a "come-and-get-it" folder, alerting the users, and they go copy/paste the new front-end file to their own folders on the network. This way, each user can update their front end when they're at a 'stopping point' without having to boot everyone out at once.
I've found that when I'm developing now, sometimes Access becomes extremely slow. Like, when I am developing a form and attempt to click a drop-down on the properties box, the drop-down arrow will push in, but it will take a few seconds before the list of options appears. Or there's tons of lag in selecting & moving controls on a form. Or lots of keyboard lag.
Then, at other times, there's no lag at all.
I'm wondering if it's because I'm linked to the same back end as the other users. I did make a reasonable effort to set up the queries, forms, reports etc. with minimal record locking, if any at all, depending on the need. But I may have missed something, or perhaps there is some other performance issue I need to address.
But I'm wondering if there is an even better way for me to set up my own development back-end .mdb, so I can be testing my code on "safe" data instead of the same live data as the rest of the users. I'm afraid that it's only a matter of time before I corrupt some data, probably at the worst possible moment.
Obviously, I could just set up a separate back-end .mdb and manually reconfigure the table links in the front end every time, using the Linked Table Manager. But I'm hoping there is a more elegant solution than that.
And I'm wondering if there are any other performance issues I should be considering in this multi-user, split database configuration.
EDIT: I should have added that I'm stuck with MS Access (not MS-SQL or any other "real" back end); for more details see my comment to this post.
If all your users are sharing the front end, that's THE WRONG CONFIGURATION.
Each user should have an individual copy of the front end. Sharing a front end is guaranteed to lead to frequent corruption of the shared front end, as well as odd corruptions of forms and modules in the front end.
It's not clear to me how you could be developing in the same copy of the front end that the end users are using, since starting with A2000, that is prohibited (because of the "monolithic save model," where the entire VBA project is stored in a single BLOB field in a single record in one of the system tables).
I really don't think the problems are caused by using the production data (though it's likely not a good idea to develop against production data, as others have said). I think they are caused by poor coding practices and lack of maintainance of your front end code.
turn off COMPILE ON DEMAND in the VBE options.
make sure you require OPTION EXPLICIT.
compile your code frequently, after every few lines of code -- to make this easy, add the COMPILE button to your VBE toolbar (while I'm at it, I also add the CALL STACK button).
periodically make a backup of your front end and decompile and recompile the code. This is accomplished by launching Access with the /decompile switch, opening your front end, closing Access, opening your front end with Access (with the SHIFT key held down to bypass the startup code), then compacting the decompiled front end (with the SHIFT key held down), then compiling the whole project and compacting one last time. You should do this before any major code release.
A few other thoughts:
you don't say if it's a Windows server. Linux servers accessed over SAMBA have exhibited problems in the past (though some people swear by them and say they're vastly faster than Windows servers), and historically Novell servers have needed to have settings tweaked to enable Jet files to be reliably edited. There are also some settings (like OPLOCKS) that can be adjusted on a Windows server to make things work better.
store your Jet MDBs in shares with short paths. \Server\Data\MyProject\MyReallyLongFolderName\Access\Databases\ is going to be much slower reading data than \Server\Databases. This really makes a huge difference.
linked tables store metadata that can become outdated. There are two easy steps and one drastic one to be taken to fix it. First, compact the back end, and then compact the front end. That's the easy one. If that doesn't help, completely delete the links and recreate them from scratch.
you might also consider distributing an MDE to your end users instead of an MDB, as it cannot uncompile (which an MDB can).
see Tony Toews's Performance FAQ for other generalized performance information.
1) Relink Access tables from code
http://www.mvps.org/access/tables/tbl0009.htm
Once I'm ready to publish a new MDE to the users I relink the tables, make the MDE and copy the MDE to the server.
2) I specifically created the free Auto FE Updater utility so that I could make changes to the FE MDE as often as I wanted and be quite confident that the next time someone went to run the app that it would pull in the latest version. For more info on the errors or the Auto FE Updater utility see the free Auto FE Updater utility at http://www.granite.ab.ca/access/autofe.htm at my website to keep the FE on each PC up to date.
3) Now when working on site at a clients I make the updates to the table structure after hours when everyone is out of the system. See HOW TO: Detect User Idle Time or Inactivity in Access 2000 (Q210297) http://support.microsoft.com/?kbid=210297 ACC: How to Detect User Idle Time or Inactivity (Q128814) http://support.microsoft.com/?kbid=128814
However we found that the code which runs on the timer event must be disabled for the programmers. Otherwise weird things start happening when you're editing code.
Also print preview would sometimes not allow the users to run a menu item to export the report to Excel or others. So you had to right click on the Previewed report to get some type of internal focus back on the report so they could then export it. This was also helped by extending the timer to five minutes.
The downside to extending the timer to five minutes was if a person stays in the same form and at the same control for considerable parts of the day, ie someone doing the same inquiries, the routine didn't realize that they had actually done something. I'll be putting in some logic sometime to reset this timer whenever they do something in the program.
4) In reference to another person commenting about scripts and such to update the schema see Compare'Em http://home.gci.net/~mike-noel/CompareEM-LITE/CompareEM.htm. While it has its quirks it does create the VBA code to update tables, fields, indexes and relationships.
Use VBA to unlink and re-link your tables to the new target when switching from dev to prod. It's been to many years for me to remember the syntax--I just know the function was simple to write.
Or use MS-Access to talk to MS-Access through ODBC, or some other data connection that lives outside of the client mdb.
As with all file base databases, you will eventually run into problems with peak usage or when you go over a small magical number somewhere between 2 and 30.
Also, Access tends to corrupt frequently, so backup, compact and repair need to be done on an frequent basis. 3rd party tools used to exist to automate this task.
As far as performance goes, the data is being processed client side, so you might want to use something like netmeter to watch how much data is going over the wire. The same principle about indexing and avoiding table scans apply to file base dbs as well.
Many good suggestions from other people. Here's my 2 millicents worth. My backend data is on server accessed through a Drive mapping. In my case, the Y drive. Production users get the mapping through a login script using active directory. Then the following scenarios are easily done by batch file:
Develop against local computer by doing a subst command in a batch file
run reports against last nights data by pointing Y to the backup server (read only)
run reports against end of month data by pointing to the right directory
test against specialized scenarios by keeping a special directory
In my environment (average 5 simultaneous users, 1000's of rows, not 10,000's.) corruption has occurred, but it's rare and manageable. Only once in the last several years have we resorted to the previous days backup. We use SQL Server for our higher volume stuff, but it's not as convenient to develop against, probably because we don't have a SQL admin on site.
You might also find some of the answers to this question (how to extract schemas from access) to be useful as well. Once you've extracted a schema using one of the techniques that were suggested you gain a whole range of new options like the ability to use source control on the schemas, as well as being able to easily build "clean" testing environments.
Edit to respond to comment:
There's no easy way to source control an Access database in it's native format, but schema files are just text files like any other. Hence, you can check them in and out of the source control software of your choice for easy version control/rollbacks.
Or course, it relies on you having a series of scripts set up to re-build your database from the schema. Once you do, it's normally fairly trivial to create an option/alternative version that rebuilds it in a different location, allowing you to build test environments from any previous committed version of the schema. I hope that clarifies a bit!
If you want to update the back end MDB schema automatically when you release a new FE to the clients then see Compare'Em http://home.gci.net/~mike-noel/CompareEM-LITE/CompareEM.htm will happily generate the VBA code need to recreate an MDB. Or the code to create the differences between two MDBs so you can do a version upgrade of the already existing BE MDB. It's a bit quirky but works.
I use it all the time.
You need to understand that a shared mdb file for the data is not a robust solution. Microsoft would suggest that SQL Server or some other server based database would be a far better solution and would allow you to use the same access front end. The migration wizard would help you make the changeover if you wanted to go that way.
As another uses pointed out, corruption will occur. It is simply a question of how often, not if.
To understand the performance issues you need to understand that to the server the mdb file with the data in it is simply that, a file. Since no code runs on the server, the server does not understand transactions, record locking etc. It simply knows that there is a file that a bunch of people are trying to read and write simultaniously.
With a database system such as SQL Server, Oracle, DB2. MySQL etc. the database program runs on the server and looks to the server like a single program accessing the database file. It is the database program (running on the server) that handles record locking, transactions, concurrency, logging, data backup/recovery and all the other nice things one wants from a database.
Since a database program designed to run on the server is designed to do that and only that, it can do it far better and more efficently that a program like Access reading an writing a shared file (mdb).
There are two rules for developing against live data
The first rule is . . . never develop
against live data. Not ever.
The second rule is . . .never develop
against live data. Not ever.
You can programatically change the bindings for linked tables, so you can write a macro to change your links when you're deploying a new version.
The application is slow because it's MS Access, and it doesn't like many concurrent users (where many is any number > 1).