MS Access Backend data corruption - corruption

I have an Access database that was designed and developed back in 1997 - 99. all user interaction is through forms and reports, there is no end user access to the backend tables. It has worked flawlessly for the last 19 plus years. Both front and back end are still in .mdb format, but the front ends which are local to the workstation and are replaced with a clean copy upon every login are running on Access 2016. There are at a maximum, 6 users in the database at one time, usually there are only 4.
Starting about 90 days ago the back end would randomly corrupt when a request to write a record was made. The error message is “Database is in an unrecognized format”. We have replaced old workstations and the Server that host the back end, in addition we replaced the switch that all computers connect to. On the workstations that were not replaced Office has been re-installed and all updates applied to it. The corruptions cannot be reproduced consistently, it happens in different forms and from different workstations randomly. After the corruption, we have to delete the lock file, compact and repair the Back end and it will work just fine until the next corruption, and the data that was attempted to be written is there, so there has been no Data loss.
The back end data was rebuilt last year to remove the random primary key values, that were created when the database was replicated over a dial up modem back when the database was first developed. The replication functionality was turned off approximately 17 years ago. The back end has been rebuilt again from scratch, each table was created in a new Database and all the index's and relationships were rebuilt. The data from each table was exported to a Text file and then imported into the new database.
There were no changes made to the front end in the prior three or four weeks before this issue started happening. Just to ensure that it was not something in the frontend, it was rolled back to a version that was working fine in February of this year, unfortunately that did not resolve the issue
None of these steps have resulted in resolving the back end corruption, and if anything, the corruption is happening more frequently. The only thing that works at this point is to have one user at a time in the database, as soon as the second user opens the frontend, the back end will corrupt within a few minutes.
Any thoughts or ideas would be greatly appreciated.
Thank you
Steve Brewer

Update:
This is a known bug introduced by one of the Office/Windows updates. See http://www.devhut.net/2018/06/13/access-bu...ognized-format/ for all the details and workaround/solution.

Related

How to force a cache refresh in MS Access

I am working on migrating a MS Access Database over to a newer SQL platform.
But, with all of the users who are currently using it, we're migrating slowly/carefully.
The first step is that we are re-writing the VBA code into C#, which is then deployed in a .dll along with the database.
Now, the VBA code calls into the C# to do the business logic, then the VBA continues to do the displays/UI, while Access still hosts the database.
The problem comes in that I have a report that is being run after the business logic from the C# in one place, and apparently MS Access has a cache, which clears every 5 seconds. So, the transaction that occurs in the C# code writes to the database, but the VBA code is still using the cache. This is causing errors, as the records added to the database (which the VBA report is trying to report on) don't exist in the cache yet...
I'm guessing that the C# .dll must be getting treated as a "second connection" to the MS Access database, which is what seems to typically cause this error in my searches (thinks that one process is writing, and the other is reading).
Since the cache is cleared out every 5 seconds, we can just put the process to sleep, and wake it up after 5 seconds, and then run the report, but that's pretty terrible for an end user.
And, making things difficult, the cache seems like it only gets used in the deployed version (so, when running from source / in debug mode, the error never happens).
Doing some searches, there seems to be plenty of people who have said "just refresh the cache." But, the question is: within VBA, how do you refresh the cache?
Any advice would be welcome.
Thanks
I've been fighting the same issue for years as I write a lot of tools around an old Powerbuilder application that has an Access MDB back end.
The cache does exist and it is VERY real. When data is inserted on a different connection than it is queried on, the cache can be directly observed and measured. It was also documented by Microsoft before they blackholed a bunch of their old articles...
Microsoft Jet has a read-cache that is updated every PageTimeout milliseconds (default is 5000ms = 5 seconds). It also has a lazy-write mechanism that operates on a separate thread to main processing and thus writes changes to disk asynchronously. These two mechanisms help boost performance, but in certain situations that require high concurrency, they may create problems.
I've found a couple workarounds that are not the best, but somewhat make due until I find something better or can re-write the app with a better back end database.
The seemingly best answer I've found (that may actually work for you since you say you need VBA) is to use JRO.RefreshCache. I've been trying to figure out how to implement this using C# or VB.net without any luck. Below is a link to a code example where you execute the RefreshCache method on your 2nd connection that needs to pull the data. I have not tested this myself.
https://documentation.help/MSJRO/jrmthrefreshcachex.htm
A workaround I've found that will deliver the query results within 500ms to 1000ms of insert time (instead of anywhere between 500 and 5000 ms - or more):
Use System.Data.ODBC instead of OleDB, with connection string: Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=;
If someone knows how to use the JRO.RefreshCache method with OLEDB and C# or VB.net, I'd be forever grateful. I believe the issue is it's looking for an ADO connection to be passed in, not an OLEDB connection.
I not aware of ANY suggesting that some 5 second cache exits? Where did this idea come from????
Furthermore, if you have 5 users, then you not going to be able to update their cache, are you?
In other words, the issue of some cache for one user still not going to solve or work with mutli-users anyway, is it?
The simple matter is if you load up a form with 100 reocrds, and then other users are ALSO working on that 100 rows, then all users will not see other changes until such time you tell access to re-load the form.
You can do this with a me.Refresh in the form, and then it will show changes made by other users (or even your c# code!!!).
However, that not really the soluion here.
How does near EVERY system deal with this issue?
Answer:
You don't, you "design" the software to take the user work flow into account.
So, in place of loading up a form with 100 rows of data? (which you should not, unless SUPER DUPER reason exists for doing that).
The you provide a UI in which the user FIRST searches for whatever it is they want to work on.
In other words, say you just booked a user on a tour. Now, they call the office back, and want to change some details of that tour. But, a different tour staff might pick up the phone. So, now a 2nd user opens the tour?
So, you solve that issue by NOT loading all the tours into that form in the first place.
you provide a search screen, so they can search for the user, find the user, maybe type in a invoice number or whatever.
You display the results in a pick list, and then launch the form to the ONE record (and perhaps detail records from child tables).
So there no concpet of a cache in Access anymore then there is in c#.
However, if you load up a datatable in c#, and then display that data?
Well, what about the other users on that system. They will not see changes to that data ANY MORE then the current access form.
So, if you want to update some data in c#? Then fine, but you need/want to do two things:
First, before you call any c# code that may update the current form reocrd? You need to FORCE a data save of that current record BEFORE you call any code, be it VBA code, or c# code that going to update that current reocrd the user is working on.
You can in Access save the current reocrd in MANY different ways, but the typical approach is:
' single record save - current record
if me.dirty then me.dirty = false
' VBA or c# code goes here.
' optional refresh the current form to reflect changes
me.Refresh
So, in most cases, it is the "design" of your software that will solve this issue.
For example, in the tour example, or in fact ANY system, the user can't work, can't update, and can't do their job UNLESS they first find/search and have a means to bring up that form + record data in the first place.
So, ANY typical good design will:
Ask the user for that name, invoce number or whatever.
Display the results of the search, and THEN allow the user to pick the record/data to work on. When they are done, they close that form and are RIGHT BACK to the search form to do battle with the next customer or task or phone call or whatever.
So, a search form might look like this:
In above, I typed in smi, and then displayed a pick list.
The user can further type in say part of the first name, and thus now get this:
So, maybe they type in a invoice number, customer number, booking number or whatever.
So, you display the results, and then they can select the row or "thing" to work on.
thus, we click on the row (or above glasses button), and then jump to the ONE record.
so, the user does whatever they have to do with the customer. Now, when done, they close the ONE thing, the ONE main reocrd.
This not only saves the data (so others in the office can now use that booking data), but it also means the data is saved. and they are NOW right back at the search screen, ready to do battle with the next customer.
So, not only does this mean we have a VERY bandwith friednly design (we only pull the one main reocrd into that form), but it also is better for work flow.
The Access form's cache thus becomes a non issue, since we only dealing with the one record.
And as I pointed out, if the system is multi-user, then you NOT going to be able to udpate and deal with multiple users cached data anyway, are you?
Think of ANY system you EVER used from a software point of view.
When you use google, does it download the WHOLE internet, and then you use ctrl-f to search megs and megs of data in the browser?
Nope!
you search first, get a list of that search, and THEN pick one!!
And when that list is display, maybe others on the internet are udpateing, and add new data - but if that was cached in your browser, then it would not work!!!
And same goes for a desktop accounting system. You don't load up all accounts, and THEN have the user go ctrl-f to search all the data. You search for the customer, invoice number and PICK ONE to work on.
And it does not make sense to load up a form with 1000 customers, and then go ctrl-f to find that customer. Same goes for a instant banking machine. It does not download ALL customers and THEN let you search. It asks you FIRST to get what you need. So, be it browser based, desktop based, or JUST ABOUT ANY software you use?
You quite much elminate the cache issue, since not pre-loading boatloads of data, but asking and letting the user search for the data they need.
So, in regards to the Access form data and cache?
If you are on a form, and call VBA code, or c# code or whatever?
If that code update the current form, you have NO MORE OR LESS of a issue when calling VBA code, or c# code!!!! If that code updates the current form, and the reocrd is dirty (has pending edits), then you get that message about the current form's reocrd having been udpated by another user!!!
So, your cache issue does NOT IN ANY WAY exist MORE or LESS as a issue in typical Access software.
As a genreal rule, if you are on a form with pending edits, and say want to pop up some form to edit releated data?
You have to ensure that pending edits are SAVED before you launch an form that can edit the same data, or run code that can/may edit that data.
As a result, ZERO cache issues should exist, and they no more or no less exist when calling sql or VBA update code in a form then calling some c# code from that form.
So, write the pending update for that form.
Then run your VBA, SQL, or c# code.
And then do a me.Refresh to display any changes made by those external routines.
there is no documetjion, or ANY article I can find that suggests some kind of 5 seocnd cache or update - it is a urban myth, and your software challenge here in regards to use c# or VBA, or even SQL server stored procedures?
They are all the same issue, and I dare say that often access is used as a front end to SQL server, and ALL OF the SAME issues exist when using SQL server with ms-access.

MS Access crashes every time I use Immediate Window

Every time I use the MS Access Immediate Window within the VBA Editor, Access crashes if I type any procedure name followed by the spacebar.
For example, I have a procedure called "CreateCEUploadFile" which takes a string parameter for a year. So, I'd like to type "CreateCEUploadFile "2019". However, as soon as I hit the spacebar after the e of File, Access freezes for a second, then crashes.
I initially thought this was specific to a database I've created. This is a database which was initially created 7 years ago, and has been worked on steadily over that time. So, I tried:
Compiling, then compacting and repairing. No change.
Decompiling the file. No change.
Re-compiling the file. No change
Creating a new database file, importing all objects. No change.
Restarting the PC. No change.
Removing Office (Office 365 Pro), restarting the PC, re-installing Office, re-starting the PC. No change.
I've now experimented, and discovered that the same issue occurs in all database files on this PC (a laptop that I've been using without issues for around 2 years). It also occurs with any call to any function (whether my own or built in), as soon as I hit a character after the function name.
In the immediate window:
? now --> works
? date --> works
? format( --> crashes as soon as I hit the spacebar`
I have now just discovered that this same issue occurs in MS Excel's VBA Immediate Window too...
Okay, so I've just found the solution.
Using the old principle of "What's changed since I last got this to work" I discovered that it seems to be a problem with my installation of Dextop.
I wanted to have a way of having multiple virtual desktops, and the built-in virtual desktops system in Windows 10 wouldn't cut it. Every time I do anything in SSMS on one desktop, it's reflected in the other.
So, I had a look around and found good reviews for Dextop. It seemed to work well - I have two different databases open in Access (one on each Desktop), and two different instances of SSMS, one pointing at each server. However, it seems to be this that was causing the Immediate Window to crash the relevant application.
Exit Dextop - all works well.
Restart Dextop - symptom immediately re-appears.
So now to try to find another alternative to Dextop....

MS Access occassional "Cannot open any more databases" error

I have an MS Access (2013) application with a split database. Everything seems to run smoothly except for occasionally I will get Error 3048: Cannot open any more databases.
The error occurs when the front end tries to run vba code which involves pulling data from the back end and will stall on any line with: Set DB = OpenDatabase() or DoCmd.RunSQL() commands.
The strange thing is that this error seems to be time based. I can access the back end hundreds of times without error if I do it quickly enough but after some time has passed (~1 hr) the error shows up. In fact, I can open the application and leave it running in the background (with no code running) then go back into it after an hour and I will get the error the first time the code tries to open the back end.
I've searched the length and breath of this site and google for solutions so I know this error has been addressed before. To save people reiterating the usual fixes I will list what I've tested for so far with no success:
Recordset limit: I'm not leaving any recordsets open, every time I open one I make sure to close it. The same for the databases. All my requests
to the back end are done via 3 or 4 vba functions and each of these has
a Rec.Close or DB.Close corresponding to every OpenRecordset()
and OpenDatabase() and I never have more than 2 recordsets open at
a time.
Control limit: I have 151 controls on the biggest form in the application so I should be below the limit (I believe this is 245 for a single form?)
Corrupt database: I've copied all my forms and code to a new Access database and run a Compact and Repair.
Machine Issue: I've tested the application on several machines and reproduced the same error.
Anyway with most of the above situations I would expect the application not to run at all, instead of running fine for a set amount of time and then crashing.
Some other points of note:
Citrix Users: The users are split between normal windows machines users who are experiencing this error and others who are using the application through a virtual desktop software (Citrix) who are having no issues. Unfortunately I don't know enough about this virtual desktop to really work out what that implies.
Background vs Foreground: Some users have claimed that the application only crashes if it has been running for a long time AND they switch over to another program and switch back. I've confirmed that simply switching between the application and other programs doesn't cause it to crash but haven't yet been able to leave it running in the foreground long enough to confirm if it crashes without switching between programs.
I've been struggling with this for days, anyone able to help me out?

After database corruption, errors are being produced

I had a split database working fine on a clients machine for over 2 years. Due to unknown circumstances the database became corrupted. And was fixed by the removal of a couple of corrupted records.
The front end has now began to produce the following errors:
2147352567
2448
These errors will be thrown individually when a user performs a certain action.
How can it be that these errors have suddenly started to show themselves up when before everything was working fine?
Without wanting to bog down this question with code, the premise of the forms when the error occurs are that:
A form is open and an excel spreadsheet may also be open that relates
to that record.
On save/close of the excel spreadsheet a corresponding field in the database record is updated.
The user decides to 'Update Excel Spreadsheet' or 'Save and Close'
The errors occur on Before_Update events on the access form
Is there any reason that these errors might have started occurring in what appeared to be a perfectly working system?
Thanks in advance for any assistance.
I have resolved the issue by including in the code an appropriate update record:
If Me.Dirty = True then
Me.Dirty = False
End if
Still don't understand how the errors began to arise though after the DB became corrupted? The forms/buttons/actions would have been used daily by the users during their working week for over 2 years.

SSMS 2012 hanging when opening multiple query windows or files

I recently upgraded from 2005 to 2012 (about 10 months). When I first started using SSMS2012 it worked great was able to open multiple windows in a particular database. For about that last 2-3 months SSMS hangs when I try to open more than 1 query window or open a file. It is random but happens a majority of the time. I have been able to interrupt the hang a few times. When I interrupt it I get the login screen and it sits there trying to log in apparently unsuccessfully. If I cancel the login and try it again with the same entries it connects just fine and things are great, but I have to do this for every window and I cannot often break into that screen before it stops responding.
I have searched extensively and have not found an answer to this problem. It only appears to be happening to a particular instance. The instance does not show any signs of issues, has been rebooted and configuration checked for inconsistencies, etc. I am at a loss. If anyone has experienced this and has been able to resolve it I would appreciate a response.
Again this is a fresh install of 2012 standard with 2005 imported databases. All indications show that it is working fine. compatibility level for a majority of the databases are still 90, until I can clear them for 11 with the software they house. I have a test environment with the restored versions on a different server and no issues result from that instance - I can open up multiples without incident. My belief is it is something with that particular instance, but I am not sure where else to look.
Thank you in advance.