Access窗体勾选复选框时出现Write Conflict写入冲突报错
Access单用户环境子窗体复选框触发写入冲突修复方案
问题复现场景
- 主窗体名称为 Update Client Details,内嵌名为 Update Phone 的子窗体,用于展示当前客户名下所有联系电话,子窗体字段结构如下:
[cID][FullName][PhoneType][PhoneNumber][Active] 1 Test ter Mobile 0899955522 [] <= 空白复选框
- 主窗体设置 Update 按钮,点击后弹出独立窗体,供用户为当前客户新增电话号码
- 用户提交新增号码后,新记录同步展示在 Update Phone 子窗体中,其中
Active复选框默认值为0(未勾选状态) - 单用户使用无并发编辑的前提下,点击Active复选框标记号码激活时,直接弹出Write Conflict写入冲突报错
参考界面





修复步骤
这个问题和多用户权限、并发锁无关,核心原因是新增号码的弹出窗体提交数据后未释放记录行锁,返回主窗体后子窗体加载同一条记录时,两个窗体的记录集同时持有编辑权限,Access判定为冲突,按以下顺序操作即可解决:
- 修正新增窗体的提交关闭逻辑
打开新增电话号码弹窗的设计视图,找到提交按钮的VBA点击事件,不要在执行完新增操作后直接关闭窗体,必须先提交挂起编辑、释放记录集引用,示例代码:
' 提交所有未保存的编辑 If Me.Dirty Then Me.Dirty = False ' 释放当前窗体持有的记录集锁 Set Me.Recordset = Nothing ' 再执行关闭窗体操作 DoCmd.Close acForm, Me.Name
注意不要只调用DoCmd.RunCommand acCmdSaveRecord就直接关窗体,该方法不会主动释放DAO/ADO记录集持有的行锁,是这类弹窗新增后触发锁冲突的最常见原因。
- 修正主窗体打开弹窗后的刷新逻辑
主窗体的Update按钮不要直接用普通模式打开新增弹窗,改用对话框模式打开,等弹窗关闭后主动刷新子窗体记录集,示例代码:
' 以对话框模式打开新增窗体,传入当前客户cID,代码会阻塞直到弹窗关闭 DoCmd.OpenForm "AddNewPhoneNumber", acNormal, , , acFormAdd, acDialog, Me.cID ' 弹窗关闭后先提交主窗体自身的挂起编辑 If Me.Dirty Then Me.Dirty = False ' 重建子窗体记录源,彻底清空旧缓存的锁状态 Me.[Update Phone].Form.RecordSource = Me.[Update Phone].Form.RecordSource
不要直接调用Me.[Update Phone].Requery,部分Access版本下Requery方法不会清理缓存的带锁记录状态,重新赋值记录源可以彻底释放旧记录集的所有锁。
- 排查表与控件绑定的隐性冲突
如果前两步操作后仍报错,逐一检查以下配置:
- 确认存储电话号码的表设置了明确主键(可设置单独的PhoneID自增主键,或cID+PhoneNumber联合主键),无主键的Access表会出现随机编辑锁冲突
- 确认
Active字段为Yes/No布尔类型,没有设置不符合类型规则的默认值,表上没有绑定自定义更新触发器 - 打开子窗体设计视图,检查Active复选框的控件来源,确认没有误绑定到主窗体的同名字段,跨窗体控件绑定会导致同时编辑两条记录触发冲突。
- 兜底兼容方案(临时修复用)
如果暂时定位不到具体锁来源,可以在子窗体的错误事件中捕获写入冲突错误,自动刷新后重试操作,代码如下:
Private Sub Form_Error(DataErr As Integer, Response As Integer) ' 捕获写入冲突、记录已被锁定类错误 If DataErr = 7787 Or DataErr = 3021 Or DataErr = 3197 Then Response = acDataErrContinue Me.Dirty = False Me.RecordSource = Me.RecordSource ' 重试复选框勾选操作 Me.Active = Not Me.Active End If End Sub
内容的提问来源于stack exchange,提问作者Hariharan Iyer
相关产品推荐
相关产品推荐

