8

我正在使用 SQL Server 迁移助手 (SSMA) 将 Access 数据库迁移到 SQL Server。Access 应用程序将继续使用,但使用链接表而不是本地表。

我在使用包含多个子表单的表单进行迁移后测试期间遇到了问题。

测试步骤:

1) 在主窗体中编辑一个字段;

2)将焦点转移到子表单中的一个字段;

3) 尝试编辑子表单中的字段。

结果:弹出错误消息:“数据已更改。在您尝试保存更改之前,另一个用户编辑了此记录并保存了更改。”

错误消息消失后​​,可以编辑子表单中的字段。如果未编辑主表单中的字段,则可以编辑子表单而不会出现错误消息。

关于可能导致此错误的任何想法?

我已经尝试在主窗体上的子窗体控件的 Enter 事件处理程序中保存主窗体记录(即,当输入包含子窗体的控件时,此事件发生在主窗体上,而不是在子窗体本身上) . 没有任何区别。我尝试在同一个子表单控件 Enter 事件中重新查询主表单,但这不起作用 - 重新查询主表单会将焦点从子表单移开,因此无法对其进行编辑。

一个 MS 论坛在子表单的 After_Update 事件中建议了 Me.Parent.Requery。那也没有用。

当我进入子表单时,SQL Profiler 显示一个更新语句,更新主表单下的表。没有其他语句命中数据库来修改数据。

我注意到一件有趣的事情:主窗体的记录源实际上是一个将两个表连接在一起的选择语句。主窗体包含可以更新记录源中每个表中的列的字段。在主窗体中编辑更新关系中的子表的字段不会导致“数据已更改”错误。该错误仅在编辑更新关系中的父表的字段时发生。我已经尝试过更新两个表中不同列的字段。结果是一致的:在父表中编辑记录会导致错误,在子表中编辑记录不会。

子表单和主表单之间的链接将子表单表中的列连接到主表单记录源中子表中的列。

顺便说一句,主窗体Record Source 中的表实际上是以1:1 的关系连接的(父表中的每条记录对应子表中的一条记录)。子表只是父表的扩展表。

如果我从头开始,我个人不会设计这样的系统,但这是我必须使用的,我希望有一些相当简单的修复,不需要对表格或表单进行重大重新设计(假设主窗体和子窗体各有 100 多个控件)。

4

3 回答 3

11

经过多次试验和错误,我解决了这个问题。在主窗体上的子窗体控件的输入事件处理程序中,我请求了子窗体本身。

例如在主窗体上:

Private Sub Subform1_Enter()
    Me.Subform1.Form.Requery
End Sub

我不知道为什么这有效,只是它确实有效。

于 2013-04-28T15:06:21.993 回答
5

This happens when a record is updated in a table, but the record source of the main form has not been refreshed to reflect the change, so Access gets conflicting information and thinks the record has been changed. See also: http://support.microsoft.com/kb/302492

于 2015-01-26T16:09:05.133 回答
1

我通过像这样编写 AfterUpdate 表单事件来解决这个问题:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    cSQL = "update UnderlinedTable set Field1=" & Me.Controls("Field1") & _
        ", Field2=" & Me.Controls("Field2") & _ ' and all other fields in your form
        " where PrimaryKey=" & Me.Recordset.Fields("PrimaryKeyField")
    ' here command to SQL server that executes this cSQL string
    Me.Requery
    Cancel = True 'stop Access updating
end sub

可以编写通用的更新前表单事件函数,该函数基于 form.recordsource 和更改的表单字段自动生成更新语句,可以从所有更新后表单事件调用表单作为参数。我为我做了这个。

于 2018-07-05T12:29:05.053 回答