Access 2010 - 使用复合主键

时间:2015-08-06 23:55:49

标签: access-vba ms-access-2010 audit-trail

我一直无法找到解决这个问题的方法,所以我希望你们中的一些人可能会有所帮助。我正在尝试为Access数据库创建审计跟踪以跟踪更改。我的许多表都有复合主键(多个字段组合在一起以唯一标识记录)。我为Audit模块获得了以下代码:

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.

Select Case .ControlType

Case acTextBox
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 & ")"
 '& cDQ & Environ("username") & cDQ & ", " _

'View evaluated statement in Immediate window.

 Debug.Print strSQL
 DoCmd.SetWarnings False
 DoCmd.RunSQL strSQL
 DoCmd.SetWarnings True
 End If

Case acComboBox
If .Value <> .OldValue Then
varBefore = .OldValue
varAfter = .Value
strControlName = .Name
'Build INSERT INTO statement.
strSQL = "INSERT INTO " _
& "Audit (EditDate, User, RecordID, SourceTable, " _
& " SourceField, BeforeValue, AfterValue) " _
& "VALUES (Now()," _
'& cDQ & Environ("username") & cDQ & ", " _
& 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


Case acListBox
If .Value <> .OldValue Then
varBefore = .OldValue
varAfter = .Value
strControlName = .Name
'Build INSERT INTO statement.
strSQL = "INSERT INTO " _
& "Audit (EditDate, User, RecordID, SourceTable, " _
& " SourceField, BeforeValue, AfterValue) " _
& "VALUES (Now()," _
& cDQ & Environ("username") & cDQ & ", " _
& 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 Select

End With
Next
Set ctl = Nothing
Exit Sub

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

End Sub

然后在单个表单的代码中,我有以下代码来运行模块:

Option Compare Database

Private Sub Form_BeforeUpdate(Cancel As Integer)
Call AuditTrail(Me, HeaderID)
End Sub

我发现当我将HeaderID替换为单值主键名称的字段名称时,代码工作正常。当我的表有多个字段构成主键时,我不知道如何格式化'HeaderID'以识别这些值的组合。我也以某种形式查找表格,但我不确定这是否会导致问题。

我收到的错误消息:

编译错误: ByRef参数类型不匹配

任何想法都将不胜感激!

谢谢你, 蒂芙尼

1 个答案:

答案 0 :(得分:0)

您的AuditTrail子例程将形式和控件作为参数,其中对数据进行编辑。所以,当你通过我的时候。以及字段(控件)的名称,您实际上将当前表单和控件传递给子例程。当您更改&#39; HeaderID&#39;除了控件名称之外的任何其他内容,您将获得“类型不匹配”#39;错误,因为你的子程序需要一个控件而不是一段数据。

您需要调整AuditTrail子例程以获取实际要存储在表中的索引值。如果您的组合ID是由三个值组成的字符串,则更改AuditTrail子例程的参数来自&#39; control&#39;到&#39;字符串&#39;。