绑定ADO断开的记录集的MS Access表单

6

我在这个主题上似乎一无所知。我可以将ADO记录集附加到表单上,但我不确定如何处理更新。我不想只使用UpdateBatch,我想能够检测到更改以进行日志记录。有人可以指点我正确的方向吗?

提供的SQL包含一个名为“ID”的自动编号键字段。

Private Sub Form_Load()
    Dim rst as Object
    Set rst = CreateObject("ADODB.Recordset")
    rst.CursorLocation = adUseClient
    '...edit out connection
    rst.Open sql, mConnection, adOpenStatic, adLockBatchOptimistic
    set rst.ActiveConnection = Nothing
    Set Me.Recordset =  rst
End Sub 

''Edit records on the form and now click save
Private Sub cmdSave_Click()
    Dim rst As Object
    Set rst = Me.Recordset
    Set rst.ActiveConnection = GetConnection
    rst.UpdateBatch
    'How do I detect deleted, added, or modified records for logging? 
End Sub

1
你觉得为什么需要这样做呢?为什么不直接将表单的Recordsource属性设置为适当的SQL字符串呢? - David-W-Fenton
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5

您应该能够使用表单的BeforeUpdate和AfterUpdate事件来检测添加和编辑。至于删除操作,您需要使用其中一个表单删除事件:BeforeDelConfirm、AfterDelConfirm或Delete。

当检测用户开始编辑记录时,Dirty事件也非常有用。

我认为您真正需要将第一个Recordset对象设置为表单级别的对象,而不是将其放在表单的Load事件中。

    Dim rst As Object

Private Sub Form_Load()
    Set rst = CreateObject("ADODB.Recordset")
    rst.CursorLocation = adUseClient
    '...edit out connection
    rst.Open sql, mConnection, adOpenStatic, adLockBatchOptimistic
    set rst.ActiveConnection = Nothing
    'You can close your connection object here now
    Set Me.Recordset =  rst
End Sub 

''Edit records on the form and now click save
Private Sub cmdSave_Click()
    Set rst.ActiveConnection = GetConnection
    rst.UpdateBatch
End Sub

Private Sub Form_Unload()
    'Offer to do batch update here if changes have been made to the recordset
    rst.Close
    Set rst = Nothing
End Sub
你可以考虑使用AuditTrail功能来记录更改。但是,如果用户没有执行批量更新,则这些更改实际上不会被应用到数据库中,因此我不确定您将如何以简单、易于理解的方式记录更改。 以下是一些可能有效的审计跟踪代码: http://www.everythingaccess.com/tutorials.asp?ID=Creating-an-Audit-Trail-(Source-Code) 我看到Fenton先生质疑为什么您需要一个断开连接的ADO记录集,而不是使用MS Access内置的DAO绑定。我知道有些情况下使用ADO记录集是有意义的,但我认为这种情况很少见。绑定到诸如XML文件之类的记录源可能是一个例子。我个人喜欢在绑定到远程SQL Server时使用它。它非常适合让Access与云端的Web服务器上的SQL Server数据库进行通信。但是,你可以使用ODBC表来做同样的事情,因此没有真正强制使用ADO记录集,只是管理DSN或ODBC表链接确实具有挑战性。 编辑1: 针对OP对事件无法捕获大量删除和复制的担忧,对于每个选择要删除的记录,Delete事件都会触发,而在用户按“是”后,AfterDelConfirm事件会触发。在粘贴时,您不太幸运,因为没有事件在用户确认粘贴后触发。一种解决方法是禁用表单中的添加并使用其他方法插入新记录。 你可以考虑另一个选择,就是使用ADO记录集事件。看起来这些事件几乎可以处理所有事情,除了一个非常关键的事情 - 返回正在编辑、删除或插入的每个记录的书签或主键。 第三个选项是为每个记录设置DateTimeModified。然后,您可以随时使用代码来遍历记录集,并记录尚未记录的更改。只需创建一个记录集副本,然后使用记录集的Filter方法,例如:
rst.Filter "DateTimeModified > " & LastLoggedDateTime
现在遍历过滤后的记录集并记录这些记录。如果必要,您可以在内存中保留原始记录集的副本(只读),并将其用于比较。请参阅此帖子:在vb6中比较两个记录集。 我同意,实现您想要的功能并没有真正简单的方法。看起来相当复杂。

感谢您的评论。我还想指出,此表单将以数据表视图显示。关于事件设置:在数据表视图中设置的事件不完整且不足以记录更改。例如,用户可以删除15行,每行都会触发正确的事件,然后在“您确定”对话框之后,删除确认事件将触发。但是,对于多行粘贴和该操作的“您确定”对话框,没有这样的设置。这破坏了依赖事件的整个设置。 - dmaruca
你测试过这个吗?最近有一个用户使用了查找和替换功能,我的审计跟踪函数记录了每个记录的更改。我不确定对于大规模删除和粘贴是否存在可捕捉事件。 - HK1
如果你不想要删除,为什么会启用删除功能呢? - David-W-Fenton
@HK1 嘿,伙计,我回来了,又读了一遍你的回答,已经有两年了。我想再次感谢你给出这么好的回应。我真的很喜欢你的日期/时间修改方法。在我的项目中,我仍然会有选择地使用这种方法,但主要是为了展示目的 - 向用户显示他们无法编辑的导入数据,并防止他们打开一个链接表格或其他表格进行编辑。如果用户具有管理员/编辑权限,我将修改表单的记录集,然后指向链接表格或本地表格并从那里进行管理。这样做简单得多。 - dmaruca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,