当表单控件(即文本框)为空时跟踪 MS Access 表单中更改的数据

Tracking the changed data in MS Access forms when controls of the form (ie. Text box) is blank

我正在使用 MS Access 数据库并跟踪用户活动,我使用了以下 VBA 模块: 在下面的代码中,我的 Access 表单的文本框中的每个更改都被插入到名为 "Audit".

的日志 table 中
Option Compare Database    
Const cDQ As String = """"    

Sub AuditTrail(frm As Form, recordid As Control)
  'Track changes to data.
  'recordid identifies the pk field's corresponding control in frm, in order to id record.
  Dim ctl As Control
  Dim varBefore As Variant
  Dim varAfter As Variant
  Dim strControlName As String
  Dim strSQL As String
  On Error GoTo ErrHandler
  'Get changed values.
  For Each ctl In frm.Controls
    With ctl
    'Avoid labels and other controls with Value property.
    If .ControlType = acTextBox Then
      If .Value <> .OldValue Then
        varBefore = .OldValue
        varAfter = .Value
        strControlName = .Name
        'Build INSERT INTO statement.
        strSQL = "INSERT INTO " _
           & "Audit (EditDate, RecordID, SourceTable, " _
           & " SourceField, BeforeValue, AfterValue) " _
           & "VALUES (Now()," _
           & cDQ & recordid.Value & cDQ & ", " _
           & cDQ & frm.RecordSource & cDQ & ", " _
           & cDQ & .Name & cDQ & ", " _
           & cDQ & varBefore & cDQ & ", " _
           & cDQ & varAfter & cDQ & ")"
        'View evaluated statement in Immediate window.
        Debug.Print strSQL
        DoCmd.SetWarnings False
        DoCmd.RunSQL strSQL
        DoCmd.SetWarnings True
      End If
      End If

    End With
  Next
  Set ctl = Nothing
  Exit Sub

ErrHandler:
  MsgBox Err.Description & vbNewLine _
   & Err.Number, vbOKOnly, "Error"
End Sub

我可以在表单的更新事件之前使用上面的代码。当我的文本框已经有一个值时,它工作得很好,但是当这些文本框是空白时,子例程不起作用。 任何建议将不胜感激。

虽然 wazz 分享的方法只要文本字段中没有引号就可以工作,但这不是方法。

正确的方法是使用参数。这样你就可以防止 SQL 注入和当你的文本字段包含引号时发生的错误。这也将避免 DoCmd.SetWarnings 代码。

strSQL = "INSERT INTO " _
           & "Audit (EditDate, RecordID, SourceTable, " _
           & " SourceField, BeforeValue, AfterValue) " _
           & "VALUES (Now(), ?, ?, ?, ?, ?)"
With CurrentDb.CreateQueryDef("", strSQL)
    .Parameters(0) = recordid.Value
    .Parameters(1) = frm.RecordSource
    .Parameters(2) = strControlName 
    .Parameters(3) = varBefore 
    .Parameters(4) = varAfter
    .Execute
End With

完全实施:

Sub AuditTrail(frm As Form, recordid As Control)
  'Track changes to data.
  'recordid identifies the pk field's corresponding control in frm, in order to id record.
  Dim ctl As Control
  Dim varBefore As Variant
  Dim varAfter As Variant
  Dim strControlName As String
  Dim strSQL As String
  On Error GoTo ErrHandler
  'Get changed values.
  For Each ctl In frm.Controls
    'Avoid labels and other controls with Value property.
    If ctl.ControlType = acTextBox Then
      If ctl.Value <> ctl.OldValue Then
        varBefore = ctl.OldValue
        varAfter = ctl.Value
        strControlName = ctl.Name
        'Build INSERT INTO statement.
        strSQL = "INSERT INTO " _
           & "Audit (EditDate, RecordID, SourceTable, " _
           & " SourceField, BeforeValue, AfterValue) " _
           & "VALUES (Now(), ?, ?, ?, ?, ?)"
        With CurrentDb.CreateQueryDef("", strSQL)
            .Parameters(0) = recordid.Value
            .Parameters(1) = frm.RecordSource
            .Parameters(2) = strControlName 
            .Parameters(3) = varBefore 
            .Parameters(4) = varAfter
            .Execute
        End With
      End If
      End If
  Next
  Set ctl = Nothing
  Exit Sub

ErrHandler:
  MsgBox Err.Description & vbNewLine _
   & Err.Number, vbOKOnly, "Error"
End Sub