Network based linked table locks for editing - ms-access

I have an issue with a table that locks over the network using ms-access. I split the database and have a front end with the user interface and the code and the back end with the linked tables.
When I open the front end and want to add data to the table it is locked for entry (no row with the little *). In VB it gives me the "operation must use an updatable query" error when I want to add the data.
This was used to work perfectly but lately I had issues. If I close the front end and go to open directly the linked table on the network I can edit the table without problem. So I should have the rights to edit the files and they are not read only.
Please advise.
Thank you

Related

SQL Server rows not editable for Access after Insert

I have this problem: I'm using a SQL Server 2008R2 backend and MS Access 2000 frontend where some tables are connected via ODBC.
Following Structure (Tables all on SQL-Server):
Import (not connected to Access)
Products (connected via ODBC to Access)
Pricing (connected via ODBC to Access)
I want to fill the Pricing table automatically with some data from Products and Import. This is supposed to run as a SQL Agent job with a T-SQL script.
I want to insert the data from "Products" with following command:
INSERT INTO Pricing (Productnr, Manufacturernr)
(SELECT Productnr, Manufacturernr
FROM Products
WHERE Valid = 1
AND Productnr NOT IN (SELECT Productnr FROM Pricing ));
Right after that the inserted rows are locked for Access, I can't change anything. If I execute sql queries with SQL Server Management Suite or if i start queries as SQL Agent jobs everything works fine.
Why are the rows locked in ms access after the query ran (even if it finished successfully)? and how can I unlock them or make it unlock itself right after the query/job ran?
Thanks
When SQL Server inserts new rows, those new rows are in fact exclusively locked to prevent other transactions from reading or manipulating them - that's by design, and it's a good thing! And it's something you cannot change - you cannot insert without those locks.
You can unlock them by committing the transaction that they're being inserted under - once they're committed to SQL Server, you can access them again normally.
The error message i get says, that the dataset has been changed by another user and if i save it, i would undo the changes of the other user. (and asks me for copying into clipboard).
This is different from "locked", and completely normal.
If you have a ODBC linked table (or form based on the table) open, and change data in the backend, Access doesn't know about the change.
You need to do a full requery (Shift+F9) in Access to reload the data, afterwards all records can be edited again.
Got the solution for my Problem now.
I had to add a timestamp row into the pricing table, so access could recognize the change.
Access loads the data into the front end when the table is first accessed. If something in the backend changes the data, you need Access to refresh it first, before you can edit it from the front end (or see the changes).
Do this by (in Access) by closing and reopening the table, or switching to the table and pressing shift-F9 as Andre suggested, or programmatically using a requery statement. You must requery, not refresh, for it to release the locks and register the changes made in SQL.

Migrating Table Macros to VBA with a now split Database

What i have is the Issues template from microsoft which is all i really need for its purpose. I have converted it so that is now no longer a web database by exporting objects as client objects.
I want to split this database so that not only multiple users can utilise it at the same time but also so it performs better.
When i split the database the macros linked to the tables go to the backend so when the front end needs to use them it errors.
Below is and example of the add comments macro that gets called when the add comment button is pressed on the front end.
And this is the macro embedded to the button
Can these be converted to VBA and interact with the backend the way it is meant to and if so where would i start. I have looked for an answer but all i find is people saying "it is fine now i have gone vba route" or similar but not actually showing it working.
Below is the converted data macro to VBA. It isn't 100% there yet as I have hard-coded the userID but this will be fixed later today, but I hope it gives a good understanding of how to convert data macros to VBA because this was a learning experience for me.
Private Sub cmdAddaComment_Click()
Dim db As dao.Database, theComments As Recordset
Set db = DBEngine.Workspaces(0).Databases(0)
Set theComments = db.OpenRecordset("Comments")
theComments.MoveLast
theComments.AddNew
theComments!IssueID = Me.ID
theComments!CommentDate = Now
theComments!Comment = Me.txtAddComment
theComments!UserID = 2
theComments.Update
Me.txtAddComment = ""
DoCmd.RepaintObject acForm, "IssueDetail"
End Sub
Before doing this, make a backup of your database. You can do that by closing down the database, then locate the .accdb file on your computer, and press Ctrl+C and Ctrl+V
You can do your own split like this:
Create a new, blank database.
Import everything EXCEPT THE TABLES from the old database
In the new database, create links to the old database tables. To do that, click on External Data - Import & Link, and then click on Access. Select the Link option, then locate the old database, and select all the tables you want to link. Note that if you see any tables that are named like "MSYS", do NOT import those. Those are system tables, and Access will handle those internally.
Now delete everything EXCEPT THE TABLES from the old database.
Your new database is now "linked" to the old database's tables, but all Forms, Reports, etc are in the new database.
If you want to split an Access DB, you have to separate TABLES from all the rest.
Queries, Macros, Forms, Reports and VBA code have to stay on the frontend, and only tables on the backend.
What you are missing are the LINKS from the frontend to the backend tables.
To do that you need to create a copy of your DB, renaming it "BE.mdb" (or accdb), delete all your objects except tables from BE.mdb.
Now on the original mdb, you need to delete every table and add a link for every deleted table to the BE.mdb corresponding table. This can be done from the Import menu, choosing "link table" instead of "Import table".

What causes a "The search key was not found in any record" error in Access 2010?

The error message "The search key was not found in any record" was appearing on one record of a table in Access 2010.
I first noticed this when accessing that record via an update query, but later found that I also got the same error when trying to delete the record.
What causes this, and how can it be resolved?
It was just a database corruption, but I was misled by it only affecting one record. A Compact and Repair sorted it immediately.
Sometimes this happens because the field name contains a leading space, ensure your field names are trimmed before and after.
Example: It happened to me when I was trying to import an Excel sheet contains the first row as field names, two of the field names was " Latitude" and " Longitude". From this post I knew the problem's cause, so I changed them to "Latitude" and "Longitude" (without the leading space), and the problem was solved.
I know this is an old post, but i just ran into this issue and none of the other answers seemed to solve or address my scenario.
Using a copy of the dbase, i had to continue to delete tables until the error message ceased.
The table at fault was a hidden, system table with the name MSysComplexColumns. I deleted it, closed the dbase and the table was auto-created upon re-opening the dbase. That completed solved it with no side effects.
In my case, this error message was triggered by the size of my Access file. When its size exceeded 2,000,000 KB, the message popped up when I was importing another document. As long as I reduced its size, the message stopped and the import process finished successfully.
Also check the database version. I was having the problem with VBA CreateDatabase(sTempDBName, dbLangGeneral) in Access 2010 where I was using a 2003 database trying to link a table in a 2010 database. When I manually tried the link I got a message about no support for linking to a later version. Creating the temp database I was trying to link to using the option dbVersion40 "CreateDatabase(sTempDBName, dbLangGeneral, dbVersion40)" cured it.

Copying to/from Dbase data using Access

I am stuck with some legacy back ends using dBase IV, and would like to be able to copy records from one table to another using an Access front end. The simple answer would be to link to the source and destination tables and run an INSERT query or similar.
However, in my situation, the back end is not a single DBF file, but there are several hundred files that I need to dynamically link to for the copy operation. Currently I have to change and refresh the link definition using the TableDefs property (in VBA) every time I wish to perform the copy operation.
The catch is the front end is shared, meaning that each user has to have a separate copy of the FE so that the linked table definitions are not modified by another user.
I was wondering is there an easy way to do this without using linked tables? I could open DAO connections to the source and destination but cannot find any simple way of copying the records (apart from one at a time). Are there anyways around this?
It is possible to run a query using the linked DBF that inserts into a DBF in another location:
INSERT INTO [dBASE III;DATABASE=z:\docs\].[dbf2.dbf]
SELECT *
FROM dbf1;
Or
INSERT INTO dbf1
SELECT *
FROM [dBASE III;DATABASE=z:\docs\].[dbf2.dbf];

solution needed - 2 users running a program

So I've developed this Access 2007 application with about 2 forms, a lot of VBA code and a bunch of tables.
Now the business wants to run this off a network drive (call it G:\ for example). My current solution (which I've already implemented is have a table similar to:
__________________
|Setting | Value |
==================
Updating 1
UpdateBy User1
So let me give you a context. When the application runs there is a button called "update" which updates the local table from a remote server so we can apply filtering. Now when two people (user1, user2) launch the application, and one person clicks update then the updating field is set to true, and the updateby is set to their name.
So User number 2 tries to update, it checks if the updating field is true, if it is then it gives them a message (to user two, not to user one).
It works beautifully right now, but here is the problem: Lets say user1 is updating, and closes his program (or taskkills it) or the power disrupts, then the application shuts off with the updating field set to to true. Now no matter who launches it, they can not update because its "already updating"
Can you guys think of a solution to this? Maybe a workaround?
Consider a different locking strategy. In the click event of your "update" button, you can first open a recordset based on your tblUpdateStatus (the table where you've been writing UpdateBy) with dbDenyWrite + dbDenyRead options.
Set rst = db.OpenRecordset("tblUpdateStatus", _
dbOpenTable, dbDenyWrite + dbDenyRead)
Then do your other operations for the "update" button. Afterward, close and release the recordset ... which releases the tblUpdateStatus lock.
Trap the error when a user is unable to open the recordset (because another user has the table locked), give them a message to try later and exit your click event subroutine.
With this approach, when user1 locks tblUpdateStatus but exits Access uncleanly, her lock on tblUpdateStatus is released. You may not even need to update tblUpdateStatus unless you want to record which user has it locked.
See Create and Use Flexible AutoNumber Fields (from the Access Cookbook) for more details about using a recordset with dbDenyWrite + dbDenyRead.
Please do not run an Access application with more than one user when you have not split the database. It will cause endless trouble. The data portion (back-end) should be put on the server and the code and forms (front-end) should be put on each users desktop.
More information: http://support.microsoft.com/kb/162522
Read my article on why you split here:
http://www.members.shaw.ca/AlbertKallal/Articles/split/index.htm
In the above, I don't just tell you to do this, but I tell you WHY you split.
It should help you a lot in terms of users tripping over each other.