I have a bound MS Access form which is updated by multiple users.
I want to keep track of any edits by the users. Currently i record whenever a record is updated by using the timestamp and username.environ function
However i would like to track the changed contents as well with an inactive flag.
For example my record is
101 | Software | Jan-2017 | $5600 | Expense for Software (desc) | Active
If someone was to make any change to it, i would like the changed record to be considered active but keep this record as inactive.
Any suggestions appreciated
The traditional way to do this sort of thing is with some sort of a flag on the record to indicate the current record (be it a boolean or a sequence number or a date stamp).
Then when you are working with the current data and you end up working on a selection from the table, pruning it down to just what is current (i.e., an sql statement with where archive_date is null or where active = 'T' or you could do it one the max value for the sequence/date stamp).
That style presents certain problems for bound forms. So your mileage may vary.
My quick and dirty way out of this would be to make a data history table (parallel structure to the one your working with, with an extra date/time field and a userid field), and then add a trigger (ideally at the database level, but you could do it on the controlling form) to log the new value in the history table.
Related
I have looked and haven't found a method on here to do this. I am assuming my search is skewed and I just missed it, if this is the case, please let me know.
Anywhooo, I have a large and unwieldy report coming out of SAP every day. Because it will often have some strangeness, we import that into an Access database so we can keep an eye on the stuff we need in our department. I am using a combination of 6 fields to create a primary key in Access. The information in those fields is about the only thing consistent I get out of this SAP report, but the remainder of the data can be considered dynamic and can change from day to day. Usually this is a matter of filling in a few blanks, Occasionally this is changing existing data, and on rare occasions, it may involve deleting data out of a handful of fields.
The SAP report is around 130 columns of data, So I'm looking for an efficient way to roll in the changes without overwriting what folks put in there manually.
EDIT:
Here is the way this is used. SAP (for reasons I'm not going to go into) sometimes will have bad data show up in the daily report. We are using Access to track and put the correct data in to something that we can generate much more accurate summaries. What the users put in is to be considered true and accurate.
The transactions we are tracking can take a long time to complete. Most take around 30 days to complete. That's why I will have blank fields on one day, and several of them to be filled in on the next. We might not get any for the next few days and then a bunch more are filled in later. That is the normal flow.
What I have to account for is the odd occasion where a mistake is made early in the process. At a certain point, an error will break SAP's ability to update anything at all in the report we have to use.
I have 3 fields set up that trigger what my users daily work is going to be. There is a logical flow so that user 1 completes what he needs to do and then that record will show up on User 2's report. These fields will also stop the general update process in an exception report if there is a difference in what is coming in from SAP, and what is already in my database.
What I am looking for is some way to systematically fill in blank fields, on existing records in access. I do not want to overwrite if something is in a field, only the null values. I can do this on one field at a time, but each record has about 130 fields. I'm wondering if there is a way I could do this in just 1 query?
Thanks all! I hope the edit makes more sense now
A simple google for "Access SQL update null values" could have yeilded you what you need. But if all you need to do is fill constant values into empty fields then something like:
UPDATE Table SET Table.field1 = VALUE
WHERE Table.field2 is NULL;
Now if this data is different for each record based on; say data from another field, then you may need to write some VBA to build that value/string for you. But otherwise if you are JUST updating null fields to include data, then a simple UPDATE statement will do
EDIT Based on new info:
So if I'm understanding correctly: you have two tables. One table with the blank fields and another table that contains the values you need.
If this is the case, you can use a similar UPDATE statement, but use an inner join to get the data you need from table B to fill in table A
UPDATE TableA INNER JOIN TableB ON TableA.KeyField = TableB.KeyField
SET TableA.NullField = TableB.NotNullField
WHERE TableA.NullField Is NULL;
I have a slight issue with MS-Access, which is as follows.
I have a table with a Timestamp column (the format of the field is Date/Time, the default value is Now()). The issue is that whenever I create a new record, the timestamp is set for the next record I am going to create, as opposed to the record I am creating.
This means that I create record 50, and the Timestamp is set for record 51. If I come back a week later, and create record 51, the Timestamp for record 51 will be a week out, and the timestamp will be set for record 52, which I will be creating at some point in the future.
You can re-create the problem by firing up MS-Access, creating a new table with a couple of fields, one of which is Date/Time and setting the Default Value of this field to Now().
Is this by design, or am I doing something dumb? If it is by design, how can I implement the type of Timestamp that I want (one where the Date/Time is set as the record is created) in MS-Access? If I am doing something dumb, what exactly am I doing?
Edit: Below is a screenshot of a newly created Access table:
I add some text to record one, the Timestamp gets set for record two:
I allow some time to pass, put some data into record two, and the timestamp doesn't change, and now record three has a timestamp:
If I close and open the table, the Timestamp for the (New) record gets updated to whenever I opened the table:
I allow some time to pass, update the record and the Timestamp stays at the time I opened the table:
As is already revealed in the comments, this problem comes from editing in the table with Now() set as the Default for your TimeStamp field.
I suggest you create a form instead of editing in the table. If you want it to look similar just use a datasheet form. Then on the Form's BeforeUpdate event put code in like this:
Me!TimeStamp = Now()
As a side note, I wouldn't use TimeStamp as a field name. Some RDBMS such as SQL Server have a data type called TimeStamp. It's best to avoid using field names that are data types or reserved words. Moving an Access database to SQL Server is extremely common and you could have problems when you try to do it.
Instead, I would create two fields. One called DateTimeEntered and another called DateTimeModified. I consider these two fields to be necessary in pretty much every table I make. If you ever want to do any kind of synchronization of records you'll wish you had at least a DateTimeModified field.
I'm trying to make access conditionally only show rows that meet a certain condition, allow me to give you some background info before I proceed :
I've created an Access form and linked it to a test DB on my machine. The particular table I am interested in contains the following (important) rows :
ID , Office, Name, SecurityNumber
The thing is, ID is not unique. There are two Office locations, and each Office has it's own set of unique ID numbers. This means that ID 10 here and there may or may not be the same person. (this data comes out of a legacy security system we're not looking to change yet, so I cannot change it)
But ID -is- unique to each Office.
SO! I created an Access form with TABS! Two tabs, one for each office. What I am trying to achieve now is :
Have the ID/Name/SecurityNumber fields for each tab populate with only rows that match it's particular 'Office' value.
Thank you for reading and thank you for helping! :D
If you want the data for the office locations presented in separate tab page controls, you could use subforms on the pages which differ only in the WHERE clause of the queries used as their record sources. So for the Office1 subform, the query could be:
SELECT ID, Office, [Name], SecurityNumber
FROM YourTable
WHERE Office = 'Office1'
ORDER BY [Name];
Then for Office2, the query would be the same except for the WHERE clause:
WHERE Office = 'Office2'
As I understand your question, that approach would do what you're asking for.
However, that's not really the easy "Access way" to do it. Instead consider a combo box control to allow your users to choose which office they want to view. In the code for the combo's after update event, either modify the SELECT statement used as the form's record source or create a filter expression an apply it.
Also, since you're pulling the form's data from SQL Server, consider whether you want your form to load every record for the selected office location. It may not be much concern if you have only a few to moderate number of rows for each location, but if you'll be dealing with multiple thousands of rows it could be. In general, you should try to avoid pulling copious amounts of data across the wire; pull sparingly instead ... only what you need for the immediate task at hand.
I am new to Access programming and am trying to determine the correct way to bind unbound textbox controls for each row in a continuous form.
As an example:
Continuous Form to display a list of invoices from an Invoice table.
Table called InvoiceItems which contains equipment, rates and hours.
I need to have a form that has a row containing invoices with a column for all available equipment types.
I was planning on having unbound textboxes for each equipment type and then when each Invoice row is loaded, hook into something like an OnRowDataBound where I could dynamically populates the equipment textboxes with the appropriate data from the InvoiceItems table.
Example:
Tables:
Invoice: InvoiceID, Date
[1, 4/10/2011]
InvoiceItems: EquipmentID, Rate, Hours
[2, 40, 1]
[3, 20, 3]
Result:
InvoiceID | Date | Shovel | Plow | DumpTruck
==================================================
1 5/10/2011 3 1 0
2 2/11/2011 1 0 1
Then each textbox control would hook into the onDirty event to update the appropriate InvoiceItem line item.
You won't be able to do this in a continuous form or a datasheet view form since changing the ControlSource property on one row affects all rows.
It's unclear to my why you would even need this option but it sounds like your data/tables might not be designed properly or properly normalized. Usually I would build my tables so that EquipType is a value you can change to show what type of equipment this row is. It appears that somehow you are using different fields for each different equipment type.
Assuming that you insist on using your current design, you could possibly cobble together a solution using Union queries but your recordset will not be updateable.
Another suggestion is to make several different textboxes on your form and change the visible property on the fly. However, this is fraught with problems because you will only be showing one of them at a time on all rows. Furthermore, you'll have to show the correct one when they move to the next record but how are you going to determine which is the correct one to show?
Judging by what you've written, you must have experience programming in .Net. Access is a different beast and it works quite well if you play by its rules. Trying to get around some standard Access behavior or design will usually result in frustration for both the programmer and the user. I think this is a case where you will need to evaluate what you're trying to do and I recommend you start by making sure your table architecture is solid. Perhaps you've actually over-normalized and will need to go back and undo some of your normalization.
Does anyone know of a way to detect when the last time a Microsoft Access table has been changed (inserted into or updated)? We used OLEDB via ADO COM to communicate with an access database programmatically and were looking for a way of detecting changes to specific tables. We don't need to know what those changes are, just that changes were made.
The only way to detect if data in the table has changed is to perform a query against the table.
You must add a column of type DATETIME to the table e.g. named LastUpdatedDate that indicates the last updated date/time of each row. Make it NOT NULL so that you will have to write an updated DATETIME value to that column for each INSERT or UPDATE. Also, set the column to have a default of DATE() for the current date stamp or NOW() for the current date/time stamp. Then add a Validation Rule or CHECK constraint e.g. CHECK (LastUpdatedDate = NOW()) to ensure the column is actually updated on each UPDATE and INSERT.
Finally, run a MAX(LastUpdatedDate) query and you will get what you need.
There isn't a way without "manually" writing to a column each time you access the table.
As others have indicated there is no way to track changes without coding it yourself.
There's a simple example at
ACC2000: How to Create an Audit Trail of Record Changes in a Form
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q197592
Audit Trail - Log changes at the record level at:
http://allenbrowne.com/AppAudit.html
The article addresses edits, inserts, and deletes for a form and subform.
Modules: Maintain a history of changes
http://www.mvps.org/access/modules/mdl0021.htm
The History Table routine is designed to write history records that track the changes made to fields in one or more tables.
You will need to implement a timestamp column in your table, and update the value during your data changes.