Access 2010 数据库中的审计跟踪

Posted

技术标签:

【中文标题】Access 2010 数据库中的审计跟踪【英文标题】:Audit trail in Access 2010 database 【发布时间】:2015-06-19 10:57:30 【问题描述】:

我正在尝试在 Access 2010 数据库中创建审计跟踪。我在 www.wvmitchell.com 上找到了一些代码,除了一个问题外,它运行良好。它记录已更新但不记录新记录或已删除记录的记录。记录这些是非常重要的。以下是我使用的信息和代码:

Option Compare Database
Option Explicit

Sub TrackChanges(F As Form)
Dim ctl As Control, frm As Form
Dim MyField As String, MyKey As Long, MyTable As String
Dim db As DAO.Database, rs As DAO.Recordset
On Error Resume Next
Set frm = F
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl__ChangeTracker")
With frm
    MyTable = .Tag
    ' find the primary key & its value, based on the Tag
    For Each ctl In .Controls
        If ctl.Tag = "PK" Then
            MyField = ctl.Name
            MyKey = ctl
            Exit For
        End If
    Next ctl
    For Each ctl In .Controls
        ' inspect only data-bound controls
        Select Case ctl.ControlType
            Case acTextBox, acComboBox, acCheckBox
                If Nz(ctl.ControlSource, "") > "" Then
                    ' if changed, record both old & new values
                    If Nz(ctl.OldValue, "")<> Nz(ctl, "") Then
                        rs.AddNew
                        rs!FormName = .Name
                        rs!MyTable = MyTable
                        rs!MyField = MyField
                        rs!MyKey = MyKey
                        rs!ChangedOn = Now()
                        rs!FieldName = ctl.Name
                        If ctl.ControlType = acCheckBox Then
                            rs!Field_OldValue = YesOrNo(ctl.OldValue)
                            rs!Field_NewValue = YesOrNo(ctl)
                        Else
                            rs!Field_OldValue = Left(Nz(ctl.OldValue, ""), 255)
                            rs!Field_NewValue = Left(Nz(ctl, ""), 255)
                        End If
                        rs!UserChanged = UserName()
                        rs!CompChanged = CompName()
                        rs.Update
                    End If
                End If
        End Select
    Next ctl
End With
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

Private Function YesOrNo(v) As String
    Select Case v
        Case -1
            YesOrNo = "Yes"
        Case 0
            YesOrNo = "No"
    End Select
End Function
    用于存储结果的表。对于文本字段,我在描述中指明了长度:

这是一个 VBA 模块,它将为您创建表格。

Option Compare Database
Option Explicit

Sub Create_tbl__ChangeTracker()
    Dim db As DAO.Database
    Dim fld As DAO.Field
    Dim idx As DAO.Index
    Dim tdf As DAO.TableDef
    '
    Set db = CurrentDb
    Set tdf = db.CreateTableDef("tbl__ChangeTracker")
With tdf
    ' ID is AutoNumber and Primary Key
    Set fld = .CreateField("ID", dbLong)
    fld.Attributes = dbAutoIncrField
    .Fields.Append fld
    Set idx = .CreateIndex("ID")
    idx.Fields = "ID"
    idx.Primary = True
    .Indexes.Append idx
    '
    ' add remaining fields
    Set fld = .CreateField("FormName", dbText, 64)
    .Fields.Append fld
    Set fld = .CreateField("MyTable", dbText, 64)
    .Fields.Append fld
    Set fld = .CreateField("MyField", dbText, 64)
    .Fields.Append fld
    Set fld = .CreateField("MyKey", dbText, 64)
    .Fields.Append fld
    Set fld = .CreateField("ChangedOn", dbDate)
    .Fields.Append fld
    Set fld = .CreateField("FieldName", dbText, 64)
    .Fields.Append fld
    Set fld = .CreateField("Field_OldValue", dbText, 255)
    .Fields.Append fld
    Set fld = .CreateField("Field_NewValue", dbText, 255)
    .Fields.Append fld
    Set fld = .CreateField("UserChanged", dbText, 128)
    .Fields.Append fld
    Set fld = .CreateField("CompChanged", dbText, 128)
    .Fields.Append fld
    Set fld = .CreateField("Action", dbtext, 64
    .Fields.Append fld
End With
db.TableDefs.Append tdf
Set idx = Nothing
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub

添加这些对象后,对每个表单进行如下修改: 1. 设置表单的 Tag 属性 = 基础表的名称。 2. 确定表单背后数据的主键,并设置 Tag 属性 = "PK"(不带引号)。该字段不必在表单上可见,它只需要在某处即可。 3.添加

Form_BeforeUpdate event and invoke the tracking code using:
   TrackChanges Me

4。如果您使用子表单,则还需要对每个子表单执行这三个步骤。

在我的数据库中,我向 tbl_ChangeTracker 添加了一个名为 Action 的文本字段。我需要知道如何编写代码来填充它。提前感谢我得到的任何帮助。

【问题讨论】:

我更喜欢使用 Allen Brown 的审计跟踪:allenbrowne.com/appaudit.html 涵盖大部分基础。 Allen Browne 的审计跟踪指定所有主键都必须是自动编号。我的数据库中的一些主键是字母和数字的组合。这就是我没有尝试他的审计追踪的原因。 【参考方案1】:

你的代码已经写好了;

                If Nz(ctl.ControlSource, "") > "" Then
                ' if changed, record both old & new values
                If Nz(ctl.OldValue, "")<> Nz(ctl, "") Then

它指定是否更改记录旧值和新值。在添加新值时,您没有任何内容可以指定要执行的操作。

在您的表格更新程序之前放置以下内容;

   If Me.NewRecord Then
        Call TrackChanges(me, "NEW")
    Else
        Call TrackChanges(me ,"EDIT")
    End If

然后使用您的审计程序将其更改为接受另一个字符串类型的参数,例如;

Sub TrackChanges(F As Form, action As String)

然后在你想要的代码中;

Select Case action
Case is = "New"
 ' code here for adding new record, as an example
Case is = "Edit"
'your code as you have it above here for edits

如果你想跟踪删除,在删除之前的事件中进行同样的事情;

Call TrackChanges(Me,"DELETE")

然后在您的 TrackChanges 过程中有另一个 Case is = "Delete" 然后是处理删除的代码。

这应该让您走上正确的道路,然后您可以使用 Action 字段执行 !action = action 以便您知道它是编辑添加还是删除等。

HTH 标记

在您的评论后编辑 1,以便您查看布局; Select Case 代码将在您的 TrackChanges 函数中。在“with Frm”之前放置选择案例。然后你想把它设置如下;

Select Case action
 Case is = "Edit"
       With frm 'etc all your code here for if you edit record
Case is = "new"
       With frm 'etc all your code here for if adding new record
End select

让我知道这是否有意义,如果没有,请给我发消息,如果你需要,我可以更深入地告诉你:)

【讨论】:

谢谢马克。这有很大帮助。我还有另一个问题。请记住,这对我来说是新的。我应该在哪里放置 Select Case 代码?我应该把它放在另一个函数中还是把它放在我拥有的代码中的某个地方,那会在哪里? 查看我对布局的更新答案,作为如何处理它的一般要点让我知道这是否有意义,如果不给我发消息,我可以更深入地告诉你,如果你需要:) 非常感谢。我会处理它并回复你。你帮了很多忙。 我编写了代码以使用 Case 语句。 With frm 保持在原来的位置,我将我的代码放在第一个 Next ctl 之后。 TrackChanges(Me, "Delete") 在删除前事件中不起作用。它在 OnDelete 事件中起作用。我想分享我的代码,以便其他人可以使用它,但我不知道该怎么做。你能告诉我怎么做吗? 很高兴你到了那里:)!感觉不错是不是嘿嘿。您始终可以编辑您的初始帖子并在最后包含作为更新。如果您也可以将我的答案标记为正确,或者您这样做(如果确实有帮助的话!)那也很棒!

以上是关于Access 2010 数据库中的审计跟踪的主要内容,如果未能解决你的问题,请参考以下文章

通过 Excel 用户窗体编辑 Access 数据库时跟踪更改(创建审计跟踪)

未绑定表单/文本框的审计跟踪

关于捕获审计跟踪的数据库设计的想法[关闭]

.oldValue 控件属性上的错误 3251

宏中的 Access 2010 SQL 错误

将 XML 审计数据存储到文件系统或 MS Access 表?