“事务中不支持操作”而在 Access 中复制/粘贴记录

DHW*_*DHW 5 ms-access ms-access-2010

将单元格从 Excel 复制/粘贴到 Access 子窗体中时,如果没有创建父记录,将导致错误 - 正如预期的那样。

问题是,发生此错误后,访问被锁定在一种状态,即输入的所有后续数据都会导致事务中不支持操作错误。当您打开该表时,您可以看到新添加的数据尚未出现在该表中 - 因此看起来 Access 实际上正在从事某种事务。

我试过点击“保存”..“刷新”..甚至添加一个 AfterInsert 事件来强制执行 commitTrans() 但没有运气 - Access 声称没有正在进行的交易

如果手动输入记录,则没有错误。该问题似乎仅在粘贴记录时发生。我猜测 Access 正在创建一个事务来处理多个记录操作,并且没有从错误中正确恢复。

我可以删除“必需”标志,它会起作用 - 但是你有孤儿记录。我在想,也许可以使用 After Insert Data Macro 来添加具有默认批次名称的新批次,并将新的 BatchID 自动填充到 Items 表中。然而,我不确定如何做到这一点。

我确实尝试使用更改前数据宏删除“必需”标志并捕获错误 - 但是虽然它减少了错误 - 它仍然产生了事务错误中不支持的相同操作

我在 Microsoft 知识库上查找了错误,但没有找到任何特定于我的情况的信息。我在 stackoverflow 中搜索了错误消息,但一无所获。

我创建了一个新数据库并能够复制该问题。

复制步骤

设置数据库

  1. 在 Access 2010 中创建新的 ACCDB 数据库
  2. 创建一个名为“批次”的表,其中包含以下字段:
    • BatchID(自动编号)(主键)
    • 批次名称(文本)
  3. 创建一个名为“Items”的表,其中包含以下字段:
    • RecordID(自动编号)(主键)
    • BatchID(长整数)
      • 必需属性设置为 True
    • 数据 - 文本
  4. 创建关系,将 Batches.BatchID 链接到 Items.BatchID
    • 包括批次中的所有记录,以及项目中的匹配记录
    • 强制参照完整性
    • 级联更新/删除
  5. 创建一个名为“表单”的表单
    • 将记录源设置为批处理
    • 添加 BatchID 和 Batch name 文本框
    • 添加子窗体/子报表控件
      • 将源对象设置为“Table.Items”
      • 将链接主字段设置为“BatchID”
      • 将链接子字段设置为“BatchID”
      • 设置“过滤空母版”= 是
  6. 创建示例数据(使用表单)
    • 批量创建新记录。
      • 设置批次名称 =“测试”
    • 在项目中创建一个新记录。
      • 参考批记录。
      • 设置数据 =“测试”

正如你所看到的,手工这很好用。

从 Excel 复制和粘贴数据

  1. 在 Excel 中
    • 从 A1-A10 为每个单元格输入一个字母:A、B、C、D、E、F、G、H、I、J
    • 突出显示单元格 A1-A10
    • 复制 (Control+C)
  2. 在 Access 中,使用表单:
    • 添加新的批次记录。它应该在 BatchID 文本框中显示“(新)”
    • 不要输入批次名称
    • 在子窗体中,单击新记录的记录选择器 (*) 以选择整行。键入 Control+V 进行粘贴。
    • 单击“您必须在‘Data.BatchID’字段中输入一个值。错误的确定”
      • 此错误可能会重复。继续点击确定
      • 如果它询问“你想抑制更多的错误信息...”回答是
    • 对于“Microsoft Access 无法粘贴的记录已插入到名为“粘贴错误”的新表中,单击“确定”。通知
    • 使用“TestName”填写批次名称文本框
    • 尝试优雅地恢复。击中逃生。更改记录。

此时 - 您应该看到输入的 BatchID、批次名称和新数据。一切似乎都按预期工作。如果您尝试刷新或导航到另一批记录 - 您将收到错误Operation not supported in transactions。Access 将继续显示此错误消息,直到我们关闭并重新打开表单。您粘贴的数据不会进入数据库。

通常,精通技术的人会意识到某些事情进展不顺利并关闭数据库并重新打开......但不幸的是,我有用户使用任何弹出框玩“打地鼠”然后尝试继续 - 所以我想让事情尽可能地防弹。

所需的解决方案

我想要一个解决这个问题的方法,它最终不会导致其他具有访问权限、重复值等的怪癖。

根据我自己的经验,使用 VBA 来“修复”密钥是不可靠的。数据宏似乎更可靠 - 但它们设置起来可能很棘手 - 它们还不是很主流(我想说stackoverflow 上应该有一个ms-access-data-macros标签,但没有然而)

Gor*_*son 1

建议的解决方法:

在 [Batches] 表中,将Required[BatchName] 字段的属性设置为Yes

Tab Stop将[BatchID] 文本框的属性更改为“否”。当表单打开时,这将使 [BatchName] 文本框获得默认焦点。

On Current表单的事件为新记​​录赋予 [BatchName] 文本框焦点 ( IsNull(Me.BatchID) = True)。

当 [BatchName] 文本框失去焦点时,使表单变脏。

Option Compare Database
Option Explicit

Dim DeletePending As Boolean

Private Sub Form_Load()
    DeletePending = False
    Me.ItemSubForm.Enabled = False  ' Disable Subform by default
End Sub

Private Sub Form_Current()
    If IsNull(Me.BatchID) Then
        Me.BatchName.SetFocus
        ' Disable Subform if BatchID is NULL
        Me.ItemSubForm.Enabled = False
    Else
        ' Enable SubForm Otherwise
        Me.ItemSubForm.Enabled = False 
    End If
End Sub

Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)
    DeletePending = True
End Sub

Private Sub Form_AfterDelConfirm(Status As Integer)
    DeletePending = False
End Sub

Private Sub BatchName_LostFocus()
    If IsNull(Me.BatchID) And Not DeletePending Then
        Me.Dirty = True
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

当用户单击子表单(并关闭 [BatchName] 文本框)时,表单会变脏并且 BatchID 会获取一个值。然后他们可以粘贴,但不会收到 [BatchID] 的“您必须输入值...”消息。如果他们还没有输入 [BatchName] 值,他们现在会收到输入提示因为现在是Required),但至少他们可以从中恢复。

世界标准时间 2013 年 11 月 9 日 18:40 更新:

在进一步研究这个问题时,我发现了两个怪癖:

  1. 如果您删除了最后一条父记录,Access 会执行此操作,然后立即在其位置创建另一个新记录。

  2. 如果您导航到“新”父记录,然后立即退出(例如,通过 和PageDownPageUp),Access 将创建一条新记录,然后将您留在该记录上,并且表单为脏。点击Esc然后移走“新”记录是有效的,并且不会导致任何错误,但它肯定会让用户感到困惑。

我已经更新了答案以尝试解决这些问题。我添加了更多 VBA 代码来跟踪“DeletePending”状态。Required = Yes我还添加了在 [Batches] 表中设置 [BatchName] 的要求。如果用户移入“新”记录然后立即再次移出,后者会变得稍微更直观(尽管稍微更烦人)。