Aug 25 2022 08:01 AM
I believe that I have found a bug in Access.
I am currently running Microsoft® Access® for Microsoft 365 MSO (Version 2207 Build 16.0.15427.20182) 64-bit .
To reproduce this bug do the following:
1. Create a new empty database.
2. Create Table1 with just 2 fields, 'ID1' - Autonumber (set as Primary Key) and a ShortText ('Desc').
3. Create Table2 with just 1 field, 'ID2' - Long (set as Primary key).
4. Populate Table1 with records.
5. Create and run an append query to copy all records from Table1 to Table2, ID1 > ID2.
6. Create a form based on Table2, and add a combo box control for field ID2 that looks up and displays 'Desc' from Table1.
7. View the form in datasheet view and apply a sort via the arrow on the column label.
8. Select and delete all records.
On my system, and 3 other computers on which I have tried this, this results in all the records also being deleted from Table1!
Is anybody else able to confirm this, or is it just me?
Aug 25 2022 01:05 PM
Aug 25 2022 06:53 PM - edited Aug 25 2022 06:53 PM
it is not a bug.
if you have Inner Join your tables in the query, Yes it will delete records on both tables.
Aug 26 2022 03:29 AM
Aug 26 2022 03:46 AM
Aug 26 2022 06:53 AM - edited Aug 26 2022 06:55 AM
I'll try it out later today, but I'm tied up for a few hours, sorry.
However, I see Arnel has joined the discussion; maybe he'll be able to respond quicker.
Aug 26 2022 07:34 AM
Aug 26 2022 01:05 PM - edited Aug 26 2022 01:09 PM
THis puzzles me. I have to do more research. I can't think of an explanation that explains this. Unfortunately, time is still a bit limited today.
However, I do see that the only control on the sample form is a combo box whose row source is table1. That implies the delete is actually operating against the records in the combo box as well as the form's recordsource.
Aug 26 2022 07:23 PM - edited Aug 26 2022 08:03 PM
Again it is not a bug.
If you are using Join in your Recordsource in your Datasheet form, and
joining on Both PK fields (which means it will result in 1=1, relationship. Table2.ID2 Inner/Left/Right Join to Table1.ID1), then it will Delete On Both tables.
SOLUTION:
1. Do not make ID2 of Table2 as PK and Do not make Unique Index to it.
Or
2. Use Dlookup() as Control Source of your "Description" Column:
=DLookup("Desc", "Table1", "ID = " & Nz([ID2], 0))
Aug 27 2022 06:30 AM
Aug 27 2022 11:50 AM
I think we have a valid explanation of this bug, and it does appear to be a bug, albeit a pretty obscure one.
From Ben Clothier:
"See, when you filter or sort something using the datasheet functionality, it will add the combobox's rowsource which must happen because when you sort, you are sorting on the displayed values which is impossible to know from the form's recordsource alone. As a consequence, it will join the combobox's rowsource to the form's recordsource and filter/sort on the columns from the combobox's rowsource.
So the bug is probably that instead of implicitly doing a DELETE <form's recordsource>.* FROM <form's recordsource> WHERE ...;, it's probably doing DELETE * FROM <form's recordsource> WHERE ...; which would result in the observed behavior. The DELETE * is an Access SQL extension and whenever we join a table in a delete query, we do have to make sure we specify the table rather than using just the asterisk to target the deletions in only that table. "
Aug 27 2022 12:09 PM
See the previous response for an explanation which I believe accounts for this bug.
Here's an alternative that deletes one record at a time from the form, whether sorted or unsorted. There may be a way to delete all of the table 2 records using a similar technique. You can implement that if you wish.
Aug 27 2022 12:10 PM
Aug 27 2022 08:01 PM
Aug 28 2022 05:30 AM - edited Aug 28 2022 05:34 AM
"Access will not distinguish which PK value belongs to which table.
therefore it will delete both."
I don't think that's entirely correct, but it does express the problem correctly, I believe.
In an Access query, this is acceptable syntax and it will delete records ONLY from table2, as required.
DELETE Table2.*
FROM Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID2;
In an Access query, this is not acceptable syntax for a delete query and won't execute, precisely because it doesn't specify which table to delete the records from.
DELETE *
FROM Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID2;
I am sure that Ben's explanation is correct with regard to the implicit join created by sorting the values in the combo box. That results in a query that does include both tables (i.e. the recordsource for the form, table2, and the rowsource for the combobox, table1) and therefore deletes all records in that query.
The result must be something like this, although it's not materialized explicitly. Remember sorting the values forces Access to bring in the rowsource (table1) to support that sort
DELETE Table1.* ,Table2.*
FROM Table1 INNER JOIN Table2 ON Table1.ID1 = Table2.ID2;
And that query will delete all records from both tables because they are now specified (incorrectly, no doubt) as the form's recordsource.
To me this does qualify as a bug in the way the form's built-in Delete function operates.
Also, I wholeheartedly agree the table design here is not appropriate and is itself part of the problem. In fact, it may well be that this particular flaw hasn't been commonly encountered is precisely because the join on two primary key fields is so unusual.
Aug 29 2022 04:47 AM
I agree that the database design isn't appropriate & that this isn't (or at least shouldn't be) an approach that is used in a real life situation
However, I disagree with @arnel_gp about this 'cascade delete' being normal behaviour
Deleting records from one table should have no effect on the records from another table UNLESS a relationship has been set with referential integrity and cascade delete. See my article: Relationships1 (isladogs.co.uk)
As the OP stated, deleting records via the form does NOT normally delete records from the other table. That is correct behaviour as there is no relationship between the tables.
Applying a sort causes the records in the unrelated table to also be deleted as he reported.
That is definitely unwanted behaviour and is reasonable to consider it as a bug.
More accurately it is an unwanted side effect that isn't normally an issue in most circumstances
It should be noted that there is still no relationship between the tables
Deleting records from Table2 directly does not affect Table1
The problem is the combo on the form which has a row source to Table1 and the Inherit Value List property is set to Yes (default value). Change it to No as in the screenshot.
Now sort the list and delete records in the form. The records in Table1 are no longer deleted
A similar issue is observed in my Combobox Zombies Puzzle (isladogs.co.uk) example app
Hope that helps
Aug 29 2022 05:57 AM
Thanks, Colin.
I had used Jet Show Plan, as Mike Wolfe suggested, without spotting anything useful yet.
Too many irons in the fire to spend a lot of time on this one.
With regard to Inherit Value List, this statement is in the documentation, emphasis added:
"The InheritValueList property is effective only when the combo box is bound to a Lookup field and the RowSourceType property is set to Value List."
The fact that is impacts this Lookup using a table does suggest a bug, since it should only effect a value list. That confuses me, anyway.
Nonetheless, I think Ben's hypothesis is on the right track. Because the form is implicitly joining the two recordsets to accomplish the sort, the delete then impacts both. But, knowing that the InheritValueList property avoids the bug is very helpful.
Aug 29 2022 06:27 AM
Aug 30 2022 02:16 AM
Thank you all for looking at this and I appreciate your comments and suggested workrounds.
I would like to make the following comments, and offer a suggestion as to how the bug can be fixed.
The final point leads to my suggestion as to how to fix this. I am not privy to the inner workings of Access but I assume that currently when a sort is applied via a column label on a form in datasheet view that a routine is run whereby
a) The OrderBy property is modified
b) The form is requeried
Surely all that needs to be done is to modify the routine which does this so that it saves any original value for the form OrderBy property, including if it is blank, and then replace that value, after the requery has been run?
Aug 30 2022 06:33 AM - edited Aug 30 2022 06:37 AM
I think we've found a satisfactory explanation for the behavior and a usable and effective work-around. That work-around is the one Colin offered. It works without having to modify the internals of accdbs. Unfortunately, as we've learned in the last few months, unanticipated regressions are all too often the end result of "simple" changes in the Windows or in Access. I can't see Microsoft putting this one very high on the list of things that could be addressed.
Also, I can't resist offering this link as a partial response to one of the points made in the final post.
Why "Simplifying" question content can be counter-productive
Pay particular attention to the second point raised, if you will please.