Access Records/Rows disappearing from lookup table - ms-access

Access 2013
I have a simple lookup table that twice in the last month a record (different record on each occasion) has disappeared.
Since the auto id of the table is used as the foreign key I am forced to drop the table and recreate it.
I don't provide any delete functionality at all to users in the Access DB and especially not to the lookup table.
I have done a global search for all references to the table in my VBA code and found it was used several times but only in select statements.
At the moment I suspect a user is fiddling with something they don't fully understand and they are inadvertently deleting the record.
What else can I do determine the cause of this problem?
Can I make the lookup table read only?

Look at the relationships window. Look at the linked tables in question and see if there is a 'Cascade Deletes' checked. If so, deleting one record will delete related records.

It turned out to be a second lookup table that had a temporary relationship defined in the query that was not required. i.e: no columns were based upon this unnecessary table. This unnecessary lookup table was simply being used as a row source for a combobox on the form.
I discovered this after I noticed the form data type was set to Dynaset (Inconsistent Updates). Why? When I tested the form with normal Dynaset the form refused to perform any updates!
When I removed the unnecessary lookup table from the query I was able to set the data type back to Dynaset with updates continuing to work and deletions no longer cascading through to my first and required lookup table.
In addition the unnecessary lookup table was actually a query that was referencing a table in another database.

Related

How to prevent a form in Access from deleting data from other tables used to filter in the data source query

I am new to MS Access and VBA coding, and what I know I had to teach myself through video tutorials and reading up on the web. I have an input Form which which gets its data from a query. The query itself gets its information from a table and another query. The reason is that the other query is what filters the data so that the current user can only see his/ her own records, and not that of others. It has been designed in such a way that if a subordinate changes from supervisor, one merely have to update the supervisor name, and all the prior data in the table for that subordinate will also then reflect for the new supervisor, and no longer the old supervisor.
The problem is that the delete button on the input Form (which was created with the button wizard) not only delete the record from the table, but also from the table used to filter the subordinates. I only want it to delete the record from the actual table used in the data source query.
How would I go about to stop it from deleting in both tables?
I have attached a snapshot of a portion of the data source query, just so that you can understand what is meant by the above. The delete button on the input Form deletes the data from the table named "TableReviewNotes" and "TableAuditorNames". It should only delete the record from "TableReviewNotes".
Thanks in advance.

MS Access - Table where all deleted items go to

I need a table where all deleted items from my main table go. I found the easiest way to do this is to copy my main table, paste the table and change the name. In my main table I went to the design tab, Create Data Macros, after delete. In the set field I put the name of the field, and for the value I put [Old].[ID] etc. My problem is this works great until I try to add in my "comments field" to the list. My comments field data type is "Long Text".
Somethings I have tried: deleting all calculated fields and adding them back in as short text (worked for some fields), Deleted all default values, deleted all validation rules.
Expected result would be for my deleted record from my main table to show up into the deleted records table. I receive no error message when deleting a record. It simply doesn't add to the to the deleted table. Thanks for looking.
Why copy tables? Create a yes/no field On your table called "Deleted." Then you can run a query for or against that field depending on if you want to see the deleted data or not. Add the field to existing queries that shouldn't show these, and set its criteria to false.

How safe using combobox to input foreign key

In a Related Tables, you need to enter a FK to link to the parent table.
You either key in the FG from memory !!!!!! or use help.
The standard procedure is to design the field as combo box AND use SQL to select the field that will help to input the ID of the parent table. So, if you want to input foreign key 3 , the combo box will display what 3 is then when you selected Access will insert 3 for you.
My question is since I can later on, edit the table and change the the value to another value, and mess the whole thing up!!! HOW can I lock my first choice so it will stay unedited ?
My second question is: Is this the only way to input the FK if you do not remember the exact ID number or there are thousands of records in the parent table.?
Re. #1
In Access 2010 you could use a trigger to check whether the value has been used in another table as a FK and not allow the change. In previous versions all you could do, would be to hide the navigation pane or make the table hidden.
Re. #2
You could use a listbox (basically the same idea as a combobox).
You could include the lookup table in the underlying query, but then there is more danger of the values getting changed, which is exactly what you were worried about in the first question.
Stick with the combobox.
You can create different versions of a form. One might have Allow Edits, No, another might be Data Entry, Yes, meaning that it can only be used to create new records.
However, suppose someone is creating a new record and they select the wrong FK by mistake. How can they correct this? You could use VBA to produce a confirmation dialog in the first instance, and perhaps an Undo button where VBA would deliberately perform the Undo. Access 2010 also has Data Macros (equivalent to triggers) that you might use to store the old and new values, and other information, when a user changes a FK value.
Access does not implement user-level security, so the user can still open and change data in the raw-data tables. You should, however, have enforced referential integrity on the table-join, so that a user cannot enter a FK that doesn't already exist as a PK in the related table.
In summary, you could add additional columns to the combobox to help the user select the correct item, and you might consider an additional confirmation dialog (a MsgBox) before a record is saved into the data-table. But you cannot prevent people from making mistakes. (Enforcing Referential Integrity will prevent nonsense data from being entered.)
Second question:
A combobox (or possibly a listbox) is the easiest way for users to enter a FK value, without relying on memory. An alternative would be to use a button (or other control and event) that opens a secondary form. This form might have some filtering features to help the user find the correct FK value. When this form is closed you would then need to write some code to update the relevant control on the main form.

MS Access trigger?

I have two tables named [Insert_Record] and [Delete_Record] in MS Access. Both tables have the same fields but one table has records whereas another table has no record.
Question: I want, whenever I delete any record from the table [Insert_Record] that entire record should automatically insert into another table, i.e: [Delete Record].
How can I accomplish this?
Access 2010 introduced event-driven Data Macros that are similar to triggers. The process described in the question can easily be done with an After Delete data macro on the [Insert_Record] table:
As I understand it, Access doesn't have triggers.
The best you can probably do is put this sort of logic into the forms that edit the table. In other words, handle the deleted event at the form level and put your insert logic there.
If you want triggers, you'll want to use a proper RDMS that supports them (MySQL, MS SQL, Oracle, many others).
EDIT: Another way to do this (which may or may not work for you) would be to add a boolean column 'IsDeleted'. That way, you can just logically delete a record instead of moving it to another table. The downside of this approach is the deleted records stay in the main table which could cause performance woes if there are lots of deletes.
Create an append query, to add records into the second table, that is executed in the On Delete Confirm event of the form you are using to delete the record from the first table.
I imagine this 'Delete' is button driven...
So program the button to first Insert the record into one table before deleting it.
Just add the VBA for the insert above the delete.
Another method which nullifies your need for another table entirely is just one column that is a boolean... Active Yes/No (Default to yes.)
If Active then it is not actually deleted when they hit delete, just set the flag to False then nothing is actually deleted, no SQL code is required and there is no risk, you can even have a column with the user who updated it print in another column
Me.Active = False
Me.UserName = 'CurrentUser Location here
Me.RecordSet.Requery
Then there is no risk of actually losing anything is there and you have a record of who flagged it last.
In the continuous form just add the Where flag Active = True then no false flags will show and it looks to the user base as if it was deleted.

How to restart counting from 1 after erasing table in MS Access?

I have table in MS Access that has an AutoNumber type in field ID
After inserting some rows, the ID has become 200
Then, I have deleted the records in the table. However, when I tried to insert a new row, I see that the ID starts with 201
How can I force the ID to restart with 1, without having to drop the table and make new a new one?
In Access 2010 or newer, go to Database Tools and click Compact and Repair Database, and it will automatically reset the ID.
You can use:
CurrentDb.Execute "ALTER TABLE yourTable ALTER COLUMN myID COUNTER(1,1)"
I hope you have no relationships that use this table, I hope it is empty, and I hope you understand that all you can (mostly) rely on an autonumber to be is unique. You can get gaps, jumps, very large or even negative numbers, depending on the circumstances. If your autonumber means something, you have a major problem waiting to happen.
In addition to all the concerns expressed about why you give a rat's ass what the ID value is (all are correct that you shouldn't), let me add this to the mix:
If you've deleted all the records from the table, compacting the database will reset the seed value back to its original value.
For a table where there are still records, and you've inserted a value into the Autonumber field that is lower than the highest value, you have to use #Remou's method to reset the seed value. This also applies if you want to reset to the Max+1 in a table where records have been deleted, e.g., 300 records, last ID of 300, delete 201-300, compact won't reset the counter (you have to use #Remou's method -- this was not the case in earlier versions of Jet, and, indeed, in early versions of Jet 4, the first Jet version that allowed manipulating the seed value programatically).
I am going to Necro this topic.
Starting around ms-access-2016, you can execute Data Definition Queries (DDQ) through Macro's
Data Definition Query
ALTER TABLE <Table> ALTER COLUMN <ID_Field> COUNTER(1,1);
Save the DDQ, with your values
Create a Macro with the appropriate logic either before this or after.
To execute this DDQ:
Add an Open Query action
Define the name of the DDQ in the Query Name field; View and Data Mode settings are not relevant and can leave the default values
WARNINGS!!!!
This will reset the AutoNumber Counter to 1
Any Referential Integrity will be summarily destroyed
Advice
Use this for Staging tables
these are tables that are never intended to persist the data they temporarily contain.
The data contained is only there until additional cleaning actions have been performed and stored in the appropriate table(s).
Once cleaning operations have been performed and the data is no longer needed, these tables are summarily purged of any data contained.
Import Tables
These are very similar to Staging Tables but tend to only have two columns: ID and RowValue
Since these are typically used to import RAW data from a general file format (TXT, RTF, CSV, XML, etc.), the data contained does not persist past the processing lifecycle
I think the only ways to do this is outlined in this article.
The article explains several methods. Here is one example:
To do this in Microsoft Office Access 2007, follow these steps:
Delete the AutoNumber field from the main table.
Make note of the AutoNumber field name.
Click the Create tab, and then click Query Design in the Other group.
In the Show Table dialog box, select the main table. Click Add, and then click Close.
Double-click the required fields in the table view of the main table to select the fields.
Select the required Sort order.
On the Design tab, click Make Table in the Query Type group. Type the new table name in the Table Name box, and then click OK.
On the Design tab, click Run in the Results group.
The following message appears:
You are about to paste # row(s) into a new table.
Click Yes to insert the rows.
Close the query.
Right-click the new table, and then click Design View.
In the Design view for the table, add an AutoNumber field that has the same field name that you deleted in step 1. Add this AutoNumber
field to the new table, and then save the table.
Close the Design view window.
Rename the main table name. Rename the new table name to the main table name.
I always use below approach. I've created one table in database as Table1 with only one column i.e. Row_Id Number (Long Integer) and its value is 0
INSERT INTO <TABLE_NAME_TO_RESET>
SELECT Row_Id AS <COLUMN_NAME_TO_RESET>
FROM Table1;
This will insert one row with 0 value in AutoNumber column, later delete that row.