After Update Event in Web Apps (1 Viewer)

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
I am new to Web Apps (Interesting, but frustrating!)

I need to capture when a record is changed

I have an area called Sales Persons Notes (Sales_Person_NotesTextBox)

When that is changed I want to update a field (SP_Notes_UpdatedTextBox) to reflect Now()

For some reason, I can't make heads of tails out of the interface.:banghead:

Can anyone give me a direction, or reference some documentation?
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Thanks for trying out our Access 2013 web apps.

Were you able to find a solution to your issue?

In general, yes you can record all data changes made to the tables if you'd like in an Access web app using data macros. You could, for example, catalog all of those changes to an audit table if you'd like within the web app.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
No I have not!

Can you point a poor befuddled old school guy in a direction other than the circles I seem to be running?

I am liking the stuff but PLEASE get some documentation! I already bought a few books, and frankly nothing on Web Apps.

Perhaps some sample code to toy with?
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Sure, I can help you with us.

Before we get started, can you describe a little bit more about your scenario? Explain the scenario without control names. The reason I ask is that depending on your scenario this might be something you should do at the data layer using data macros or at the UI layer using UI macros.

Can you describe your need here a little more?

Thanks,

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
l ultimately need to record all changes in a table called Quote Requests so I suspect I need it at table level, but I am clueless, so feel free to guide me like a blind man!

I wish to simply insert the whole record into another table every time it is changed (meaning any field within the record is changed). I have done this with VBA in the past, but I ignored Macros because I got the impression they were being discontinued.

This table would keep the original index reference from the first table, and have a distinct index for each entry. For example, if I have the first table with one entry which was changed 12 times, I would have 12 entries in the second table.

I want to capture when it was changed, and ideally, who changed it.

Is something this complex feasible in a Web app? And if you can actually help, link me to YOUR books, because the three I bought didn't help at all and I will GLADLY buy all of them!
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Thank you for the additional information, that was just what I needed. Your scenario is exactly something I needed to implement just recently in a web app I created for use by the Windows division.

I'll walk you through the steps you should take to implement this using a generic table as an example. Hopefully you should be able to adapt to your specific scenario. If you get stuck on something along the way, just let me know.

Your scenario should definitely be addressed using data macros because the logic applied here would execute no matter how the data is changed. If you tried to do this using UI macros at the UI layer in web app views, that logic wouldn't run, for example, if a user happened to changed the data using a table or query datasheet within Access client.

Let's assume you have a table called Table1 and you have fields in that table called ID, Field1, Field2, and Field3. The first thing you should do is create another table in the web app to track all data changes to Table1. You will hide this table from view in the browser user interface.

Create another table called Table1AuditTrail (you can name it anything you'd like of course) and then add two fields to the table for each field you have in Table1. Be sure to match the data types.

For example, assume Field1 was Short Text, Field2 was Number, and Field3 was Date and Time. Create this structure in the audit trail table:
ID
Field1Old - Data type is Short Text
Field1New - Data type is Short Text
Field2Old - Data type is Number
Field2New- Data type is Number
Field3Old - Data type is Date and Time
Field3New - Data type is Date and Time
LastEditTimeStamp - Data type is Date and Time

The "old" fields will record what the data was before any potential data change and the "new" fields will contain what the data was changed to.

That last field will record the date and time the last update was made. Set the default value of this field to be =Now() at the table level. And also use the Subtype Date with time to record the date and time. Be sure to hide this audit trail in the Table Selector so users don't see it in their web browser. Do you know how to do that?

I should point out this one way to achieve the scenario. There are probably other ways to do this but for the app I was working on, they wanted to see all changes before and after in one record for each time a record was updated.

The next step we will take is to write a data macro in the On Update event of Table1 to write any changes to the audit table.

Let me know after you've completed these steps and then we'll walk through creating the data macro logic. If you have any issues so far, just let me know.

By the way, since you mentioned my books, Access web apps are brand new for Access 2013. Most competitor books I've seen barely touch the subject in one chapter. I devoted 600 pages to cover web apps in my 2013 book so I'm not surprised to hear you didn't find much information in other books.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
Done and standing bye!

I did not create an old / new for the index or the "Date Created" field in the table?

Should I? Otherwise I am ready to role!
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Ok, glad you're making progress.

We need to add one more field to the audit trail table which will be a lookup field to the ID value of the first table. We will use this to relate all changes made back to its original record.

So if your first table has ID as the primary key, create a new field in the audit trail field called something like Table1ID (name as you see fit) and select the Lookup field option. In the lookup wizard dialog select the first table, choose any display value you want but you can just select the ID field from the first table as your display value too. Save those changes now to the audit trail table.

There is no need to have an old and new time stamp field in the audit trail table per your question from the last post.

Now we need to define the data macro logic to record any data changes.
Follow these steps.

1. Open the master table in design view. In my example, it is Table1.

2. Click the On Update button in the Ribbon to define logic for this event. Access will fire this logic whenever data is updated in Table1. Access will now open the macro design window.

3. Essentially what we want to do (in English) is the following:
- Set a local variable to the ID value of the current record. We will push this value into the lookup field of the audit trail table to relate it back to this one.
- Set local variables to the old value and new values of each field in the master table. You use the OLD property to capture the value before it was changed.
- Create a new record in the audit trail log and use the SetField action to record all of this data into the appropriate tracking fields.
- The time stamp field in the audit trail table will be recorded automatically using the Now() default value so no need to write anything to that field in the audit trail log.

Does all of that make sense?

4. OK, let's get started.
I've attached a screenshot of what the data macro logic will look like to the bottom of this post. Take a few minutes and just study this to understand the macro logic in place and it how it relates to my explanation above. Note that I've added in extra macro comments to further explain. Keep in mind here that my field and table names are for just an example. You'll have to adjust for your specific app.

5. You can either type/input that into the empty macro window manually or just copy and paste the below logic I have posted here as an example to get you started and see how it should look. If you start with my example logic, just adjust the table and field names appropriately. To copy and paste this logic, do the following:
- Copy the logic below (it is in XML format) to your clipboard. Be sure you start exactly with < character below and the ending > character and copy that all to your clipboard.
- Click on the macro design surface away from any other objects - just click the empty white surface so your focus is there.
- Now press CRTL+V to paste all that macro logic from your clipboard onto the macro design window.
- It should just all appear now magically in your window. Let me know if this step doesn't work.

Here is the logic:

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2010/12/application"><DataMacro Event="AfterUpdate"><Statements><Comment>Record all changes to the audit log table.</Comment><Comment>Grab the ID value to relate it back using the lookup field.</Comment><Action Name="SetLocalVar"><Argument Name="Name">varRecordID</Argument><ExpressionArgument Name="Value"><Expression><Original>[ID]</Original><Identifier Name="ID"/></Expression></ExpressionArgument></Action><Comment>Set local variables to the old and new values in each field.</Comment><Action Name="SetLocalVar"><Argument Name="Name">varField1Old</Argument><ExpressionArgument Name="Value"><Expression><Original>[Old].[Field1]</Original><Identifier Name="Old.Field1"/></Expression></ExpressionArgument></Action><Action Name="SetLocalVar"><Argument Name="Name">varField1New</Argument><ExpressionArgument Name="Value"><Expression><Original>[Field1]</Original><Identifier Name="Field1"/></Expression></ExpressionArgument></Action><Action Name="SetLocalVar"><Argument Name="Name">varField2Old</Argument><ExpressionArgument Name="Value"><Expression><Original>[Old].[Field2]</Original><Identifier Name="Old.Field2"/></Expression></ExpressionArgument></Action><Action Name="SetLocalVar"><Argument Name="Name">varField2New</Argument><ExpressionArgument Name="Value"><Expression><Original>[Field2]</Original><Identifier Name="Field2"/></Expression></ExpressionArgument></Action><Comment>Create a new record in the audit log table using these variable values.</Comment><CreateRecord><Data><Reference>Table1AuditTrail</Reference></Data><Statements><Action Name="SetField"><Argument Name="Field">[Table1AuditTrail].[Table1ID]</Argument><ExpressionArgument Name="Value"><Expression><Original>[varRecordID]</Original><Identifier Name="varRecordID"/></Expression></ExpressionArgument></Action><Action Name="SetField"><Argument Name="Field">[Table1AuditTrail].[Field1Old]</Argument><ExpressionArgument Name="Value"><Expression><Original>[varField1Old]</Original><Identifier Name="varField1Old"/></Expression></ExpressionArgument></Action><Action Name="SetField"><Argument Name="Field">[Table1AuditTrail].[Field1New]</Argument><ExpressionArgument Name="Value"><Expression><Original>[varField1New]</Original><Identifier Name="varField1New"/></Expression></ExpressionArgument></Action><Action Name="SetField"><Argument Name="Field">[Table1AuditTrail].[Field2Old]</Argument><ExpressionArgument Name="Value"><Expression><Original>[varField2Old]</Original><Identifier Name="varField2Old"/></Expression></ExpressionArgument></Action><Action Name="SetField"><Argument Name="Field">[Table1AuditTrail].[Field2New]</Argument><ExpressionArgument Name="Value"><Expression><Original>[varField2New]</Original><Identifier Name="varField2New"/></Expression></ExpressionArgument></Action></Statements></CreateRecord></Statements></DataMacro></DataMacros>

6. Once you adjust the logic for your field and table names, save the macro changes. If you make a mistake with field and table names, Access will display an error message when you try to save the macro logic and inform you that it could not find something. You won't be able to save until you correct everything.

7. Save the master table after you saved the macro changes.

8. Now test it out by switching to datasheet view for the master table right within client and update an existing record. After you make a change and save it, open up the audit trail table and verify a new record was created there and it displays the old and new values from each field.

That should do it. Let me know how it goes and if you run into any issues.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

Attachments

  • MacroScreenshot.png
    MacroScreenshot.png
    44.4 KB · Views: 366

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
I have errors saying "Unable to resolve the reference to Quote Requests (My main table)

Name="SetLocalVar"><Argument Name="Name">varRecordID</Argument><ExpressionArgument Name="Value"><Expression><Original>[Quote Requests].[ID]</Original><Identifier Name="Quote Requests.ID"/></Expression></ExpressionArgument></Action></Statements></DataMacro></DataMacros>
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Could you attach the following to a new post here:
1. A screenshot of the Quote Requests table in design view (so I can see the field names and data types).
2. A screenshot of your audit trail in design view as well (so I can see the field names here too)

Attach a screenshot of those here so I can then help you build the necessary data macro logic.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Thanks for the screenshots, that is very helpful.

Follow these steps:
1. Close all open objects
2. Open the Quote Requests table in Design view
3. Click the On Update Ribbon button to open this event
4. Delete everything you have in there already. All of it; all the logic you previously entered.
5. Use the attached text file to this post and copy and paste in all of the logic from that text file directly into the On Update event.
6. Save and close the macro window. It "should" save without errors.
7. Try it out now. Change an existing record in the Quote Requests table and then open up the Audit of Quote Requests table and verify all changes were recorded.
8. Sit back and say, "Booyah, that's the ticket!"

Hope that helps,

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

Attachments

  • MacroLogic.txt
    12.7 KB · Views: 293

William Demuth

Registered User.
Local time
Today, 11:09
Joined
Feb 16, 2011
Messages
35
Dude! This ROCKS!!

Books being ordered!!

This is a powerful tool being built here. With this template available MANY awesome things are possible

Profound thanks. I have tons of more questions, but I shall save them for future postings, so you can help others!!!
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi William,

Excellent, I'm pleased to hear the macro logic I provided fits your specific need. Be sure to study the macro logic to understand what I did so you can apply similar techniques in other scenarios for your Access web apps.

Feel free to post additional questions about Access web apps if you run into issues. I can't promise I'll see and answer all of them but including web app in the title will help.

Hope you enjoy the book. Good luck with your studies of Access web apps.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

DB505050

Registered User.
Local time
Today, 10:09
Joined
Nov 15, 2012
Messages
16
I am an experienced Access VBA and SQL Server developer and I think this is an amazing tool that I am just getting into.

I have a question on this same subject though.

I want to insert only the specific field changed into an audit table. I see the event Update([Field]) which tells if a field is updated. Is it possible for me to catch the specific field updated, and insert that only into the audit table? I want my table to have this format

ID
TableName
FieldName
PreviousValue
NewValue
PrimaryKeyID
DateChanged

Thoughts? I want to capture the field name, insert the old and new value, and the unique identifier would go in the PrimaryKeyID field.
 

AccessJunkie

Senior Managing Editor
Local time
Today, 08:09
Joined
May 11, 2006
Messages
278
Hi,

Yes, the scenario you describe of capturing changes to just specific fields is entirely possible using data macro logic in Access 2013 web apps. By using the Update function you can determine if that specific field was updated during the table's On Update event and write the old and new values to a separate audit trail table.

--------------------
Jeff Conrad - Access Junkie - MVP Alumnus
Senior SDET - Access Test Team - Microsoft Corporation

Author - Microsoft Access 2013 Inside Out
Author - Microsoft Access 2010 Inside Out
Co-author - Microsoft Office Access 2007 Inside Out
Access 2007/2010/2013 Info: http://www.AccessJunkie.com

----------
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.mspx
----------
 

DB505050

Registered User.
Local time
Today, 10:09
Joined
Nov 15, 2012
Messages
16
Hi,

Yes, the scenario you describe of capturing changes to just specific fields is entirely possible using data macro logic in Access 2013 web apps. By using the Update function you can determine if that specific field was updated during the table's On Update event and write the old and new values to a separate audit trail table.

Thanks for the reply. I know that I can check a specific field, and maybe that isn't what you mean, but I mean something much more dynamic.

For instance, if I have 50 fields, hypothetically, I do not want to create logic naming and checking all 50 fields. I would like for it to just tell me which fields were updated. Is that possible and if so, could you point me to what function could help me?

Or am I stuck checking field by field? Thanks.
 

Users who are viewing this thread

Top Bottom