Module - Audit Trail: Read Only Error (1 Viewer)

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Hello All,

I have a module that is called in the BeforeUpdate event of most of my forms (See code below)

There is a button that will open a query with the table information so i can see the log entries. I've noticed that when I have this query open it will cause a read-only error when there is new or edited information being entered into the forms and it will not capture those instances into the table.

Is there a way to be able to see the real-time entries without disrupting the data entry happening in the forms being monitored? Im a little lost as to whether there is something in the code that can be changed to fix this or what I can do to make sure there is no interruption to data entry when the form

Module:

SQL:
Option Compare Database

Sub AuditChanges(IDField As String, UserAction As String)
    On Error GoTo AuditChanges_Err
    Dim cnn As ADODB.Connection
    Dim rst As ADODB.Recordset
    Dim ctl As Control
    Dim datTimeCheck As Date
    Dim strUserID As String
    Set cnn = CurrentProject.Connection
    Set rst = New ADODB.Recordset
    rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic
    datTimeCheck = Now()
    strUserID = CurrentUser()
    Select Case UserAction
        Case "EDIT"
            For Each ctl In Screen.ActiveForm.Controls
                If ctl.Tag = "Audit" Then
                    If Nz(ctl.Value) <> Nz(ctl.OldValue) Then
                        With rst
                            .AddNew
                            ![DateTime] = datTimeCheck
                            ![UserName] = strUserID
                            ![FormName] = Screen.ActiveForm.Name
                            ![Action] = UserAction
                            ![RecordID] = Screen.ActiveForm.Controls(IDField).Value
                            ![FieldName] = ctl.ControlSource
                            ![OldValue] = ctl.OldValue
                            ![NewValue] = ctl.Value
                            .Update
                        End With
                    End If
                End If
            Next ctl
        Case Else
            With rst
                .AddNew
                ![DateTime] = datTimeCheck
                ![UserName] = strUserID
                ![FormName] = Screen.ActiveForm.Name
                ![Action] = UserAction
                ![RecordID] = Screen.ActiveForm.Controls(IDField).Value
                .Update
            End With
    End Select
AuditChanges_Exit:
    On Error Resume Next
    rst.Close
    cnn.Close
    Set rst = Nothing
    Set cnn = Nothing
    Exit Sub
AuditChanges_Err:
    MsgBox Err.Description, vbCritical, "ERROR!"
    Resume AuditChanges_Exit
End Sub
 
Last edited by a moderator:

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 22:14
Joined
Oct 29, 2018
Messages
21,449
Hi. Do you know which line is causing the error? If you go to debug mode, can you verify if you were able to open the recordset with optimistic lock?
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Im not 100% on that. How would i go about checking if it is open with optimistic lock?
 

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:14
Joined
Aug 30, 2003
Messages
36,123
FYI, this line:

rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic

is opening the entire table every time, which could turn into a performance problem at some point. This is one way around it:

rst.Open "SELECT * FROM tblAuditTrail WHERE 1=0", cnn, adOpenDynamic, adLockOptimistic

or slightly more efficient but I didn't know the field name:

rst.Open "SELECT * FROM tblAuditTrail WHERE KeyFieldName = 0", cnn, adOpenDynamic, adLockOptimistic

Edit: I think one of the options could also make it append only, but I don't generally use ADO so not sure of the syntax.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
I should also mention that the code is built into the front-end of the my database but I have the table on the back-end. Should the module and/or the form/query be on the back-end as well?
 

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:14
Joined
Aug 30, 2003
Messages
36,123
No, the forms and code should be in the front end.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
FYI, this line:

rst.Open "SELECT * FROM tblAuditTrail", cnn, adOpenDynamic, adLockOptimistic

is opening the entire table every time, which could turn into a performance problem at some point. This is one way around it:

rst.Open "SELECT * FROM tblAuditTrail WHERE 1=0", cnn, adOpenDynamic, adLockOptimistic

or slightly more efficient but I didn't know the field name:

rst.Open "SELECT * FROM tblAuditTrail WHERE KeyFieldName = 0", cnn, adOpenDynamic, adLockOptimistic

Edit: I think one of the options could also make it append only, but I don't generally use ADO so not sure of the syntax.


in the "WHERE" statement what field name are we looking for here? I just tried the AuditTrailID as the KeyFieldName and no such luck, I still get a read only error when I save.
 

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:14
Joined
Aug 30, 2003
Messages
36,123
My post was not aimed at solving the current problem, just preventing a future one. Temporarily comment out

On Error GoTo AuditChanges_Err

run the code so you can hit debug and see what line the code is erroring on.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
My post was not aimed at solving the current problem, just preventing a future one. Temporarily comment out

On Error GoTo AuditChanges_Err

run the code so you can hit debug and see what line the code is erroring on.

Understood. I used the AuditTrailID, Im assuming that would be the field name needed for that part of the statement.

Run-Time error '-2147217911(80040e09)':
Cannot.update Object

Its erroring on the following line (in red):

Case Else
With rst
.AddNew
![DateTime] = datTimeCheck
![UserName] = strUserID
![FormName] = Screen.ActiveForm.Name
![Action] = UserAction
![RecordID] = Screen.ActiveForm.Controls(IDField).Value
.Update
End With
 

pbaldy

Wino Moderator
Staff member
Local time
Yesterday, 22:14
Joined
Aug 30, 2003
Messages
36,123
I don't use ADO much so I'll let theDBguy follow up on his thoughts. Presuming the table is linked, can you add a record directly in the linked table?
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
I don't use ADO much so I'll let theDBguy follow up on his thoughts. Presuming the table is linked, can you add a record directly in the linked table?

Yes. I can edit it directly through the linked table.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Hi. Do you know which line is causing the error? If you go to debug mode, can you verify if you were able to open the recordset with optimistic lock?

Any thoughts about the error or anything i may be missing?
 

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 22:14
Joined
Oct 29, 2018
Messages
21,449
Any thoughts about the error or anything i may be missing?
Hi. I just did a quick test to see if an open table would not allow me to add a new record using ADO. Unfortunately (or fortunately), I didn't get any errors. So, maybe the problem is with your query. Can you please post the SQL statement for your query? Thanks.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Hi. I just did a quick test to see if an open table would not allow me to add a new record using ADO. Unfortunately (or fortunately), I didn't get any errors. So, maybe the problem is with your query. Can you please post the SQL statement for your query? Thanks.

qryAuditTrail

SELECT tblAuditTrail.DateTime, tblAuditTrail.UserName, tblAuditTrail.Action, tblAuditTrail.FormName, tblAuditTrail.FieldName, tblAuditTrail.OldValue, tblAuditTrail.NewValue, tblAuditTrail.RecordID, tblAuditTrail.AuditTrailID
FROM tblAuditTrail
ORDER BY tblAuditTrail.DateTime DESC;
 

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 22:14
Joined
Oct 29, 2018
Messages
21,449
qryAuditTrail

SELECT tblAuditTrail.DateTime, tblAuditTrail.UserName, tblAuditTrail.Action, tblAuditTrail.FormName, tblAuditTrail.FieldName, tblAuditTrail.OldValue, tblAuditTrail.NewValue, tblAuditTrail.RecordID, tblAuditTrail.AuditTrailID
FROM tblAuditTrail
ORDER BY tblAuditTrail.DateTime DESC;
Looks straightforward enough. You may have to post a sample copy of your db just in case the problem is actually coming from elsewhere. Otherwise, you might consider switching to DAO and hope it doesn't have the same problem - but no guarantees there, since I am not having any issues with ADO.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Looks straightforward enough. You may have to post a sample copy of your db just in case the problem is actually coming from elsewhere. Otherwise, you might consider switching to DAO and hope it doesn't have the same problem - but no guarantees there, since I am not having any issues with ADO.

The back-end alone is more than 500mb and the front end is about 150mb. Not sure if this would impact anything but my front-end is .accdb and my back-end is .mdb - I did this recently to use updated features on the front-end but maintain the user-security. A little more on our set up: Runs off a NAS server through our internal network. I created localized front end versions for each user that are mapped to the NAS server but they all point to the same back-end file.

What would switching to DAO entail? Would i just need to change the terms "ADO" to "DAO"?
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
Looks straightforward enough. You may have to post a sample copy of your db just in case the problem is actually coming from elsewhere. Otherwise, you might consider switching to DAO and hope it doesn't have the same problem - but no guarantees there, since I am not having any issues with ADO.

Would you need the front-end and back or just the front?
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
I think i resolved the issue:

I just changed the onclick event to open the table in read-only mode. This seems to have stopped the issue. I dont need to open the information as a query or a form, I was just trying to lock it down so no one could edit in the information if they clicked that button.

Could it have been that previously in the Onclick event for this cmdbutton the query/form was opening in acReadOnly?
 
Last edited:

theDBguy

I’m here to help
Staff member
Local time
Yesterday, 22:14
Joined
Oct 29, 2018
Messages
21,449
I think we would only need enough to duplicate the issue. You can convert any necessary linked table into a local table.
 

evictme

Registered User.
Local time
Today, 00:14
Joined
May 18, 2011
Messages
168
I think we would only need enough to duplicate the issue. You can convert any necessary linked table into a local table.

Now I created a NEW query with the same exact info from the tblAuditTrail and am opening that with the onclick event of the Switchboard button. The issue is not coming up again.

it seems that the new query is the best route. Interesting situation. I couldnt understand why that was happening but if I can use this new query without the same issue than I am satisfied.

Thank you for your help @theDBguy and @pbaldy
 

Users who are viewing this thread

Top Bottom