Track Changes to Table

  • Thread starter Thread starter mtonkovich
  • Start date Start date
M

mtonkovich

Dear NG - Yes, I'm brand new so I will apologize in advance for being
such a pest. Lets say you run an update query and at a later date
decide you want to see those records that were updated. Short of
creating a new variable such as "ModbyQry4568" and setting it to 1 in
the update query (with the balance of the unaffected records keeping
their default value of 0) is there an easy way to track which records
were modified by a given update query?

Thanks in advance.

Mike
 
My method of dealing with this is to use an append query on a copy of
the table with an extra column for the dateModified.

The append query has all the same criteria as your update query and
copies all the data that you are going to update into the logging table
along with now() as the date. Now run your append query.

Cheers,
Jason Lepack
 
Jason - Wow. Looks like I've kept you busy today. I hate to sound
ignorant, but I'm not sure I follow every thing. Let's say I want to
replace the value of KILLDATE with the value of CHECKDATE but only when
KILLDATE < 09/30/2006 and CHECKDATE >= 09/30/2006. I guess what it
boils down to, is I don't know how to update records with an append
query.

Sorry for the really dumb questions.

Mike
 
Ok Simple Example:

tbl_part:
part_id - Autonumber - PK
part_name - Text
part_cost - Currency
part_modified - Date/Time

tbl_part_log:
part_id - Number
part_name - Text
part_cost - Currency
part_modified - Date/Time

(Note: There is no PK in tbl_part_log. Do not link these tables to
each other.)

Create an unbound form frm_setDate with two text boxes (txtCheckDate
(Format = Short Date) and txtBoundaryDate (Format = Short Date)) and a
button (cmdUpdate). Don't worry about the button yet.

Create a new Query in design view. Include all fields from tbl_part.
Now set your criteria for part_modified to:

<[forms]![frm_setDate]![txtBoundaryDate]

Save this query as "qry_sel_part".

Open your set Date form and set your txtBoundaryDate to 9/30/2006 and
run this query and make sure that it works as planned. (Note: The
frm_setDate must be open)

Now we want to add those records to the logging table before we update
them. So we need an append query. Open "qry_sel_part" in design view
and change it to an append query. Select tbl_part_log as the table to
append to. Check that the "Append To" fields all match, the only one
missing is the logging date. so in "Field" in the next blank column
put now() and the Append To as part_log_date. This will note that this
field was appended on the current date at the current time. Save this
query as "qry_app_part_log". Test the query with the datasheet view
and make sure it's still getting the right data and then run it with
"!". Notice that all your records are now backed up in the logging
table.

Next is the update query. Open qry_sel_part in design view again.
This time change it to an update query. Set the "update To" for
part_modified to:

[forms]![frm_setDate]![txtCheckDate]

Save this query as "qry_upd_part_modified".

Last thing to do is go back to your form and make it work. Right click
on cmdUpdate and click properties. Go to Events. For the On Click
event click the drop down arrow and click "Event Procedure". This
opens the vba editor. In cmdUpdate_Click put this code:

If txtCheckDate >= txtBoundaryDate Then
DoCmd.OpenQuery "qry_app_part_log"
DoCmd.OpenQuery "qry_upd_part_modified"
Else
MsgBox "Check Date must be >= Boundary Date"
End If

Save your form and open it. Click update and your data will be backed
up to your log and modified in your table.

Now notice that it prompts you for input when you attempt to modify
your tables with these queries. This can be avoided by putting
"DoCmd.SetWarnings False" before you run the queries and
"DoCmd.SetWarnings True" after. A word of warning: If you forget to
turn them back to true then you won't get warnings about anything from
access, such as saving, or anything. Always make sure to turn them off
as late as possible in your code and on as soon as possible.

Now, take this principle and put it to good use.

Cheers,
Jason Lepack
 
Jason - Geees - you went to all that trouble for me? Thank you very
much. Before I set down to do this, I thought it best to read it over
first. I'm clear on everything down to the point where you use the
term "logging" table. I'm sure this has nothing to do with cutting
timber. Could you elaborate a bit on that?

I really do appreciate your help.

Mike

Ok Simple Example:

tbl_part:
part_id - Autonumber - PK
part_name - Text
part_cost - Currency
part_modified - Date/Time

tbl_part_log:
part_id - Number
part_name - Text
part_cost - Currency
part_modified - Date/Time

(Note: There is no PK in tbl_part_log. Do not link these tables to
each other.)

Create an unbound form frm_setDate with two text boxes (txtCheckDate
(Format = Short Date) and txtBoundaryDate (Format = Short Date)) and a
button (cmdUpdate). Don't worry about the button yet.

Create a new Query in design view. Include all fields from tbl_part.
Now set your criteria for part_modified to:

<[forms]![frm_setDate]![txtBoundaryDate]

Save this query as "qry_sel_part".

Open your set Date form and set your txtBoundaryDate to 9/30/2006 and
run this query and make sure that it works as planned. (Note: The
frm_setDate must be open)

Now we want to add those records to the logging table before we update
them. So we need an append query. Open "qry_sel_part" in design view
and change it to an append query. Select tbl_part_log as the table to
append to. Check that the "Append To" fields all match, the only one
missing is the logging date. so in "Field" in the next blank column
put now() and the Append To as part_log_date. This will note that this
field was appended on the current date at the current time. Save this
query as "qry_app_part_log". Test the query with the datasheet view
and make sure it's still getting the right data and then run it with
"!". Notice that all your records are now backed up in the logging
table.

Next is the update query. Open qry_sel_part in design view again.
This time change it to an update query. Set the "update To" for
part_modified to:

[forms]![frm_setDate]![txtCheckDate]

Save this query as "qry_upd_part_modified".

Last thing to do is go back to your form and make it work. Right click
on cmdUpdate and click properties. Go to Events. For the On Click
event click the drop down arrow and click "Event Procedure". This
opens the vba editor. In cmdUpdate_Click put this code:

If txtCheckDate >= txtBoundaryDate Then
DoCmd.OpenQuery "qry_app_part_log"
DoCmd.OpenQuery "qry_upd_part_modified"
Else
MsgBox "Check Date must be >= Boundary Date"
End If

Save your form and open it. Click update and your data will be backed
up to your log and modified in your table.

Now notice that it prompts you for input when you attempt to modify
your tables with these queries. This can be avoided by putting
"DoCmd.SetWarnings False" before you run the queries and
"DoCmd.SetWarnings True" after. A word of warning: If you forget to
turn them back to true then you won't get warnings about anything from
access, such as saving, or anything. Always make sure to turn them off
as late as possible in your code and on as soon as possible.

Now, take this principle and put it to good use.

Cheers,
Jason Lepack
Jason - Wow. Looks like I've kept you busy today. I hate to sound
ignorant, but I'm not sure I follow every thing. Let's say I want to
replace the value of KILLDATE with the value of CHECKDATE but only when
KILLDATE < 09/30/2006 and CHECKDATE >= 09/30/2006. I guess what it
boils down to, is I don't know how to update records with an append
query.

Sorry for the really dumb questions.

Mike
 
Take for example that we have a part:

1, "1/4 Screw", $0.10, 12/01/2006

However, if I were to run that form with the dates:

Boundary Date: 12/02/2006
Check Date: 12/10/2006

My part table would now have:

1, "1/4 Screw, $0.10, 12/10/2006

My logging table would have:
1, "1/4 Screw", $0.10, 12/01/2006, (12/09/2006 13:38) This is when I
write this.

The "log" is a tracking of the data. Hope this makes a little more
sense.

Cheers,
Jason Lepack

Jason - Geees - you went to all that trouble for me? Thank you very
much. Before I set down to do this, I thought it best to read it over
first. I'm clear on everything down to the point where you use the
term "logging" table. I'm sure this has nothing to do with cutting
timber. Could you elaborate a bit on that?

I really do appreciate your help.

Mike

Ok Simple Example:

tbl_part:
part_id - Autonumber - PK
part_name - Text
part_cost - Currency
part_modified - Date/Time

tbl_part_log:
part_id - Number
part_name - Text
part_cost - Currency
part_modified - Date/Time

(Note: There is no PK in tbl_part_log. Do not link these tables to
each other.)

Create an unbound form frm_setDate with two text boxes (txtCheckDate
(Format = Short Date) and txtBoundaryDate (Format = Short Date)) and a
button (cmdUpdate). Don't worry about the button yet.

Create a new Query in design view. Include all fields from tbl_part.
Now set your criteria for part_modified to:

<[forms]![frm_setDate]![txtBoundaryDate]

Save this query as "qry_sel_part".

Open your set Date form and set your txtBoundaryDate to 9/30/2006 and
run this query and make sure that it works as planned. (Note: The
frm_setDate must be open)

Now we want to add those records to the logging table before we update
them. So we need an append query. Open "qry_sel_part" in design view
and change it to an append query. Select tbl_part_log as the table to
append to. Check that the "Append To" fields all match, the only one
missing is the logging date. so in "Field" in the next blank column
put now() and the Append To as part_log_date. This will note that this
field was appended on the current date at the current time. Save this
query as "qry_app_part_log". Test the query with the datasheet view
and make sure it's still getting the right data and then run it with
"!". Notice that all your records are now backed up in the logging
table.

Next is the update query. Open qry_sel_part in design view again.
This time change it to an update query. Set the "update To" for
part_modified to:

[forms]![frm_setDate]![txtCheckDate]

Save this query as "qry_upd_part_modified".

Last thing to do is go back to your form and make it work. Right click
on cmdUpdate and click properties. Go to Events. For the On Click
event click the drop down arrow and click "Event Procedure". This
opens the vba editor. In cmdUpdate_Click put this code:

If txtCheckDate >= txtBoundaryDate Then
DoCmd.OpenQuery "qry_app_part_log"
DoCmd.OpenQuery "qry_upd_part_modified"
Else
MsgBox "Check Date must be >= Boundary Date"
End If

Save your form and open it. Click update and your data will be backed
up to your log and modified in your table.

Now notice that it prompts you for input when you attempt to modify
your tables with these queries. This can be avoided by putting
"DoCmd.SetWarnings False" before you run the queries and
"DoCmd.SetWarnings True" after. A word of warning: If you forget to
turn them back to true then you won't get warnings about anything from
access, such as saving, or anything. Always make sure to turn them off
as late as possible in your code and on as soon as possible.

Now, take this principle and put it to good use.

Cheers,
Jason Lepack
Jason - Wow. Looks like I've kept you busy today. I hate to sound
ignorant, but I'm not sure I follow every thing. Let's say I want to
replace the value of KILLDATE with the value of CHECKDATE but only when
KILLDATE < 09/30/2006 and CHECKDATE >= 09/30/2006. I guess what it
boils down to, is I don't know how to update records with an append
query.

Sorry for the really dumb questions.

Mike

jlepack wrote:
My method of dealing with this is to use an append query on a copy of
the table with an extra column for the dateModified.

The append query has all the same criteria as your update query and
copies all the data that you are going to update into the logging table
along with now() as the date. Now run your append query.

Cheers,
Jason Lepack

(e-mail address removed) wrote:
Dear NG - Yes, I'm brand new so I will apologize in advance for being
such a pest. Lets say you run an update query and at a later date
decide you want to see those records that were updated. Short of
creating a new variable such as "ModbyQry4568" and setting it to 1 in
the update query (with the balance of the unaffected records keeping
their default value of 0) is there an easy way to track which records
were modified by a given update query?

Thanks in advance.

Mike
 
Jason - Thanks for the clarification. I'm going to try and tackle that
assignment today! I'll let you know how it goes.

Mike said:
Take for example that we have a part:

1, "1/4 Screw", $0.10, 12/01/2006

However, if I were to run that form with the dates:

Boundary Date: 12/02/2006
Check Date: 12/10/2006

My part table would now have:

1, "1/4 Screw, $0.10, 12/10/2006

My logging table would have:
1, "1/4 Screw", $0.10, 12/01/2006, (12/09/2006 13:38) This is when I
write this.

The "log" is a tracking of the data. Hope this makes a little more
sense.

Cheers,
Jason Lepack

Jason - Geees - you went to all that trouble for me? Thank you very
much. Before I set down to do this, I thought it best to read it over
first. I'm clear on everything down to the point where you use the
term "logging" table. I'm sure this has nothing to do with cutting
timber. Could you elaborate a bit on that?

I really do appreciate your help.

Mike

Ok Simple Example:

tbl_part:
part_id - Autonumber - PK
part_name - Text
part_cost - Currency
part_modified - Date/Time

tbl_part_log:
part_id - Number
part_name - Text
part_cost - Currency
part_modified - Date/Time

(Note: There is no PK in tbl_part_log. Do not link these tables to
each other.)

Create an unbound form frm_setDate with two text boxes (txtCheckDate
(Format = Short Date) and txtBoundaryDate (Format = Short Date)) and a
button (cmdUpdate). Don't worry about the button yet.

Create a new Query in design view. Include all fields from tbl_part.
Now set your criteria for part_modified to:

<[forms]![frm_setDate]![txtBoundaryDate]

Save this query as "qry_sel_part".

Open your set Date form and set your txtBoundaryDate to 9/30/2006 and
run this query and make sure that it works as planned. (Note: The
frm_setDate must be open)

Now we want to add those records to the logging table before we update
them. So we need an append query. Open "qry_sel_part" in design view
and change it to an append query. Select tbl_part_log as the table to
append to. Check that the "Append To" fields all match, the only one
missing is the logging date. so in "Field" in the next blank column
put now() and the Append To as part_log_date. This will note that this
field was appended on the current date at the current time. Save this
query as "qry_app_part_log". Test the query with the datasheet view
and make sure it's still getting the right data and then run it with
"!". Notice that all your records are now backed up in the logging
table.

Next is the update query. Open qry_sel_part in design view again.
This time change it to an update query. Set the "update To" for
part_modified to:

[forms]![frm_setDate]![txtCheckDate]

Save this query as "qry_upd_part_modified".

Last thing to do is go back to your form and make it work. Right click
on cmdUpdate and click properties. Go to Events. For the On Click
event click the drop down arrow and click "Event Procedure". This
opens the vba editor. In cmdUpdate_Click put this code:

If txtCheckDate >= txtBoundaryDate Then
DoCmd.OpenQuery "qry_app_part_log"
DoCmd.OpenQuery "qry_upd_part_modified"
Else
MsgBox "Check Date must be >= Boundary Date"
End If

Save your form and open it. Click update and your data will be backed
up to your log and modified in your table.

Now notice that it prompts you for input when you attempt to modify
your tables with these queries. This can be avoided by putting
"DoCmd.SetWarnings False" before you run the queries and
"DoCmd.SetWarnings True" after. A word of warning: If you forget to
turn them back to true then you won't get warnings about anything from
access, such as saving, or anything. Always make sure to turn them off
as late as possible in your code and on as soon as possible.

Now, take this principle and put it to good use.

Cheers,
Jason Lepack
(e-mail address removed) wrote:
Jason - Wow. Looks like I've kept you busy today. I hate to sound
ignorant, but I'm not sure I follow every thing. Let's say I want to
replace the value of KILLDATE with the value of CHECKDATE but only when
KILLDATE < 09/30/2006 and CHECKDATE >= 09/30/2006. I guess what it
boils down to, is I don't know how to update records with an append
query.

Sorry for the really dumb questions.

Mike

jlepack wrote:
My method of dealing with this is to use an append query on a copy of
the table with an extra column for the dateModified.

The append query has all the same criteria as your update query and
copies all the data that you are going to update into the logging table
along with now() as the date. Now run your append query.

Cheers,
Jason Lepack

(e-mail address removed) wrote:
Dear NG - Yes, I'm brand new so I will apologize in advance for being
such a pest. Lets say you run an update query and at a later date
decide you want to see those records that were updated. Short of
creating a new variable such as "ModbyQry4568" and setting it to 1 in
the update query (with the balance of the unaffected records keeping
their default value of 0) is there an easy way to track which records
were modified by a given update query?

Thanks in advance.

Mike
 
jlepack said:
My method of dealing with this is to use an append query on a copy of
the table with an extra column for the dateModified.

The append query has all the same criteria as your update query and
copies all the data that you are going to update into the logging table
along with now() as the date. Now run your append query.

This is a standard trick known as a transaction log table. However, I
don't see how it can be implemented in Jet. With triggers, how do you
control UPDATEs to the original table? You could remove UPDATE
permissions from the base table and create a SQL PROCEDURE to control
the UPDATE but, considering you can only do one operation in a single
Jet SQL statement, how do you simultaneously UPDATE the original table
and INSERT to the transaction log table?

Jamie.

--
 
Tonk said:
Jason - What does this mean in plain English?

You mean what Jamie wrote? Well what he's saying is right, if you're
data table is getting modified every few seconds then my method won't
really work. If your data gets modified every few minutes, hours,
days, etc then my method will work just fine.
 
Yes. Thank you for the clarification!

Tonk said:
You mean what Jamie wrote? Well what he's saying is right, if you're
data table is getting modified every few seconds then my method won't
really work. If your data gets modified every few minutes, hours,
days, etc then my method will work just fine.
 
Actually, I believe what Jamie was trying to point out is that your
description talks about having 2 separate queries (one to update the table,
and one to insert data into the log table), and that there's no way in
Access to have that happen automatically (to have the 2 queries tied
together, so that every time the table gets updated, an insert is made to
the log table). SQL Server gives you the ability to have triggers: whenever
you insert into the table, the trigger would automatically insert into the
log table, but Jet doesn't support triggers.

In other words, your approach will only work if people update the table
through your form. If they write a query to update the table, or if they
update the table using a different front-end, there's no way to perform the
logging.
 
Back
Top