How to track users that open a table in Microsoft Access - vba

I am trying to do an audit trail in Microsoft Access and I need a way to track when users open a table, not a form. Is there a way to run a function every time a table is opened?

Unfortunately, no events are fired when opening tables or queries in a MS Access database. If you do need to have this functionality, there are two options that I can think of, both involve hiding or restricting direct access to the tables:
Build a dashboard form, with a command button to open each table and use the Click event of the button to perform your auditing procedure. you'll be able to audit the opening of each table, but not closing. Use database table triggers to do the audit of data updates.
Create datasheet view forms of all your tables, and give access to these forms to the user instead of the tables. You'll be able to use all the supported form events to perform your audit, such as opening, closing, data updates.
You can build a combination of both to achieve your goal.

Unfortantly this would have to be done at the UI or application level, not the data engine level.
Access since 2010 does have table events and procedural code that can run at the engine level (store procedures). These table triggers and procedural code run independent of Access, and VBA code. In fact if .net or outside applications (non access) even update Access tables with ODBC, then these table triggers and store procedure code will run.
So, these features in the Access data engine (ACE) would allow some kind of audit trail and logging system to be created.
However, JUST WHO opens a table? No, that feature is not available in even SQL server, and most data engines don't have this ability (with the exception of trace features, but these are for testing, and debugging, and cause significant slow downs if such kinds of "logging" is turned on. In fact, ACE also has what is called show-plan. This will show the query plan used by ACE data engine for each and every query. But again, as noted, this kind of logging is for debugging and not suitable for tracking the "act" of a table open.
However, like SQL server, the Access data engine does have table event triggers, but they only run for updates, inserts, deletes.
Even with SQL server, you are limited to such table events. To be fair, SQL server does also have events for "DML" operations (ACE does not). So, drop of tables, or even schema modifications can fire events, the Access ACE engine cannot.
All in all?
Even with SQL server, to track/log who opend what table? You quite much need to do this at the UI/applicaiton level and not the data engine level.
If the Access application is built well, then users will never open a table directly anyway - and this holds true for any well written program - you never open/use tables directly anyway the instant you build a application in Access as opposed to just editing and view some tables like how one would in say Excel.
So, you would have to attach some code in the forms on-load. It is quite common to do this, and in several applications, we for example have a "edit" button on a form. The form can be viewed, but to edit, you have to first un-lock. When you click on un-lock, then that event is logged. As a result, we can see a nice list of all users (people) who editing that record. But, we don't log "just" the act of having opened and view the form that displays data from the table.
However, it certainly would be possible to log, and track such actions, but as noted, this would occur at the application level - not data engine level.

Related

I'm a new CDS/Dataverse user and am wondering why there are so many columns in new tables?

I'm new to CDS/Dataverse, coming from the SQL Server world. I created a new Dataverse table and there are over a dozen columns in my "new" table (e.g. "status", "version number"). Apparently these are added automatically. Why is this?
Also, there doesn't seem to be a way to view a grid of data (like I can with SQL Server) for quick review/modification of the data. Is there a way to view data visually like this?
Any tips for a new user, coming from SQL Server, would be appreciated. Thanks.
Edit: clarified the main question with examples (column names). (thanks David)
I am also new to CDS/Dataverse, so the following is a limited understanding from what I have explored so far.
The idea behind Dataverse is that it gives you a pre-built schema that follows best-practice for you build off of, so that you spend less time worrying about building a comprehensive data schema, creating tables, and how to relate them all together, and more time building applications in Power Apps.
For example, amongst the several dozen tables it generates from the get-go is Account and Contact. The former is for organisational entities and the latter is for single-person entities. You can go straight into adding your user records in one of these tables and take advantage of bits of Power Apps functionality already hooked up to these tables. You do not have to spend time thinking up column names, creating the table, making sure it hooks up to all the other Dataverse tables, testing whether the Power Apps functionality works with it correctly etc.
It is much the same story with the automatically generated columns for new tables: they are all there to maintain a best-practice schema and functionality for Power Apps. For example, the extra columns give you good auditing with the data you add, including when a row was created, modified, who created the row etc. The important thing is to start from what you want to build, and not get too caught up in the extra tables/columns. After a bit of research, you'll probably find you can utilise some more tables/columns in your design.
Viewing and adding data is very tedious -- it seems to take 5 clicks and several seconds to load the bit of data you want, which is eons in comparison to doing it in SQL Server. I believe it is how it is due to Microsoft's attempt to make it "user friendly".
Anyhow, the standard way to view data, starting from the main Power Apps view is:
From the right-hand side pane, click Data
Click Tables
From the list of tables, click your table
Along the top row, click Data
There is an alternative method that allows you to view the Dataverse tables in SSMS – see link below:
https://www.strategy365.co.uk/using-sql-to-query-the-common-data-service/
To import data in bulk:
Click on Data from the top drop-down menu > Get data.
Importing data from Excel is free. To import from other sources, including SQL Server, I believe is a paid service (although I think you may be able to do this on the free Community Plan).

Method for updating tables that users are looking at?

I'm looking for a method or solution to allow for a table to be updated that others are running select queries on?
We have an MS SQL Database storing tables which are linked through ODBC to an Access Database front-end.
We're trying to have a query run an update on one of these linked tables but often it is interrupted by users running select statements on the table to look at data though forms inside access.
Is there a way to maybe create a copy of this database table for the users to look at so that the table can still be updated?
I was thinking maybe a transaction but can you perform transactions for select statements? Do they work that way?
The error we get from inside access when we try to run the update while a user has the table open is:
Any help is much appreciated,
Cheers
As a general rule, this should not be occurring. Those reports should not lock nor prevent the sql system from not allowing inserts.
For a quick fix, you can (should) link the reports to some sql server views for their source. And use this for the view:
SELECT * from tblHotels WITH (NOLOCK)
In fact in MOST cases this locking occurs due to combo boxes being driven by a larger table in from SQL server - if the query does not complete (and access has the nasty ability to STOP the flow of data, then you get a sql server table lock).
You also can see the above "holding" of a lock when you launch a form with a LARGE dataset If access does not finish pulling the table/query from SQL server - again a holding lock on the table can remain.
However, I as a general rule NOT seen this occur for reports.
However, it not all clear how the reports are being used and how their data sources are setup.
But, as noted, the quick fix is to create some views for the reports, and use the no-lock hint as per above. That will prevent the tables from holding locks.
Another HUGE idea? For the reports, if they often use some date range or other critera? MAKE 100% sure that sql server has index on the filter or critera. If you don't, then SQL server will scan/lock the whole table. This advice ALSO applies VERY much to say a form in which you filter - put indexing (sql server side) on those common used columns.
And in fact, the notes about the combo box above? We found that JUST adding a indexing to the sort column used in the combo box made most if not all locking issues go away.
Another fix that often works - and requires ZERO changes to the ms-access client side software?
You can change this on the server:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
The above also will in most cases fix the locking issue.

Access database multiple users

Hello i have a database created with only Microsoft access (meaning no sql have been used) is it possible to make multiple users use it from different computers and the datas they input gets updated in all the computers?
Can someone just briefly tell me how if the answer is yes,
Much appreciated
I have on several occasions used the following technique with success:
(1) Split the Access Database in two:
The Back End: This database should contain the shared tables.
The Front End: A database for forms, queries and basically everything except tables.
Instead of actual tables, this database should contain "linked" versions of those tables which are held in the "back end".
(2) There is a central copy of the front-end database, but no-one opens this directly. Instead, they run a batch file which creates a local copy of that central front-end, and then opens that.
This setup has the advantage that the central "front-end" remains unused, and therefore isn't locked, and so the developer can edit it. The users will get the updates whenever they next launch the database using the batch file.
A second advantage is that the "backend" can be upsized to a "proper" database, and the front-end could then remain largely unchanged, just that the linked tables would no longer be in another Access Database.

Running a script when a table is updated in Microsoft SQL Server

I recently created a fairly lengthy SQL query script that takes the information of some base tables like forecast, bill of materials, part information and so on to automatically create a production schedule.
The script itself works well, but whenever something in those base tables changes the query script needs to be rerun (the script itself involves first dropping the tables created by the query, and then basically running the longer query of creating and dropping tables to get to the final schedule).
To make things easier on the front end user, my intention was to create a front end through access to allow the users to update the necessary base data.
My question is, is there a way to set something up either through Microsoft SSMS or Access (2016) that would run this script automatically whenever these tables were updated?
My initial search showed a lot of people talking about SQL Server Agent being able to automate queries, but I was not able to find anything regarding running a script when a table is updated, only scheduling things based on time frequency.
Ideally I think the easiest option would be if it were possible on the Access front end to allow the user to run this script by just pushing a button on a form, but I am open to whatever options would achieve the same goal.
Thanks in advance.

Is there an easy way to track all changes in a SQL 2005 Database

I've been tasked with hooking in our product with another third party product. One of the things I need to do is mimic some of the third-party's product functionality when adding new "projects" - which can touch several database tables. Is there any way to add some kind of global hook to a database that would record all changes made to data?
I'd like to add the hook, create a project using the third-party application, then check out what all tables were affected.
I know it's more than just new rows as well, I've come across a number of count fields that look to be incremented for new projects and I worry that there might be other records that are modified on a new project insert, and not just new rows being added.
Thanks for any help
~Prescott
I can think of the following ways you can track changes
Run SQL Server Profiler which will capture all queries that run on the server. You can filter these by database, schema or a set of tables, etc.
Use a 3rd party Transaction Log reader. This is very much a less intrusive process. You have to ensure that you are set to FULL recovery on the database.
Make sure the log will not be reused:
the database is in full recovery mode (true full, with an initial backup)
the log backup maintenance tasks are suspended for the duration of the test
Then:
write down the current database LSN
run your 3rd party project create
check the newly added log information with select * from ::fn_log(oldcurrentLSN, NULL);
All write operations will apear in the log. From the physical operation (allocation unit ID) you can get to the logical operation (object id).
Now that being said, you should probably have a decent understanding of the 3rd party schema and data model if you plan to interact with it straight at the database level. If you are planning to update the 3rd party tool and you don't even know what tables to update, you'll more than likely end up corrupting its data.