从主表单转换为子表单时“数据已更改”错误

时间:2013-04-25 14:42:56

标签: ms-access access-vba odbc ms-access-2007

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

我在迁移后测试期间遇到了一个问题,其中包含一些包含多个子表单的表单。

测试步骤:

1)编辑主窗体中的字段;

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

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

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

解除错误消息后,可以编辑子表单中的字段。如果未编辑主窗体中的字段,则可以编辑子窗体而不显示错误消息。

有关可能导致此错误的原因的任何想法?

我已经尝试在主窗体上的子窗体控件的Enter事件处理程序中保存主窗体记录(即此事件发生在主窗体上,当输入包含子窗体的控件时,而不是在子窗体上形成自己)。没有任何区别。我尝试在相同的子窗体控件Enter事件中重新查找主窗体,但这不起作用 - 重新查找主窗体将焦点移离子窗体,因此无法编辑。

MS论坛在子表单的After_Update事件中建议了Me.Parent.Requery。这也不起作用。

当我进入子表单时,SQL事件探查器显示单个更新语句,更新主表单下的表。没有其他声明命中数据库来修改数据。

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

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

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

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

3 个答案:

答案 0 :(得分:11)

经过多次反复试验,我解决了这个问题。在主窗体上的子窗体控件的enter事件处理程序中,我重新查询了子窗体本身。

例如,在主要表格上:

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

我不知道为什么会有效,只有它有效。

答案 1 :(得分:4)

当在表中更新记录时会发生这种情况,但主表单的记录源尚未刷新以反映更改,因此Access会收到冲突的信息并认为记录已更改。另见:http://support.microsoft.com/kb/302492

答案 2 :(得分: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

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