【问题标题】:MS Access Form Bound to ADO Disconnected RecordsetMS Access 表单绑定到 ADO 断开连接的记录集
【发布时间】:2011-08-04 05:56:24
【问题描述】:

我似乎对这个问题一无所知。我可以将 ADO 记录集附加到表单,但我不确定如何处理更新。我不想只更新批处理,我希望能够检测到为记录目的而更改的内容。谁能指出我正确的方向?

提供的 SQL 包含一个 Key 字段,它是一个名为“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

【问题讨论】:

  • 为什么你觉得你需要这样做?为什么不直接将表单的 Recordsource 属性设置为适当的 SQL 字符串?

标签: vba ms-access-2007 ado recordset


【解决方案1】:

您应该能够使用表格 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

现在遍历过滤的记录集并记录记录。如有必要,您可以将原始记录集的副本保留在内存中(只读)并将其用于比较。看看这个帖子:compare two record sets in vb6

我同意没有真正简单的方法来做你想做的事。它似乎相当复杂。

【讨论】:

  • 感谢您的 cmets。我还想指出,此表单将显示在数据表视图中。 RE 事件:数据表视图中的事件设置不完整,不足以记录更改。例如,用户可以删除 15 行,并且每行都会触发所有适当的事件,然后在“您确定”对话框之后触发删除确认事件。但是,没有这样的多行粘贴设置和“你确定”对话框。这打破了依赖事件的整个设置。
  • 你测试过这个吗?我最近有一个用户使用 Find&Replace,我的 Audit Trail 功能记录了每条记录的更改。我不相信没有可捕获的大量删除和大量粘贴事件。
  • 如果您不想要删除,为什么要启用它们?
  • @HK1 嘿伙计刚回来,2 年后再次阅读您的答案。我只想再次感谢您的如此出色的回应。我真的很喜欢你修改日期/时间的想法。我在我的项目中仍然很少使用这种方法,但主要仅用于显示目的 - 向用户显示他们不允许编辑的导入数据,并阻止他们打开链接表或其他内容并在那里进行编辑。如果用户具有管理员/编辑权限,我将只修改表单的记录集,然后指向链接或本地表并从那里进行管理。这样就容易多了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多