Vba 防止关闭按钮在MS Access中保存记录
在Microsoft Access窗体中,只要当前记录发生更改,绑定控件中的任何更改都会以静默方式保存到数据库表中。这很好,但我不希望在用户关闭表单时发生这种情况,因为这与许多人的预期正好相反 最好的例子是,当您试图关闭包含未保存更改的excel文件时,它会询问是否应放弃更改。这正是我试图在Access中实现的,但在VBA中找不到任何方法捕获close按钮的事件 表单的卸载事件是当有人单击关闭按钮时触发的第一个事件,但此时更改已写入数据库Vba 防止关闭按钮在MS Access中保存记录,vba,ms-access-2007,Vba,Ms Access 2007,在Microsoft Access窗体中,只要当前记录发生更改,绑定控件中的任何更改都会以静默方式保存到数据库表中。这很好,但我不希望在用户关闭表单时发生这种情况,因为这与许多人的预期正好相反 最好的例子是,当您试图关闭包含未保存更改的excel文件时,它会询问是否应放弃更改。这正是我试图在Access中实现的,但在VBA中找不到任何方法捕获close按钮的事件 表单的卸载事件是当有人单击关闭按钮时触发的第一个事件,但此时更改已写入数据库 这是可能的,还是我必须创建自己的关闭按钮?我可以为这些琐
这是可能的,还是我必须创建自己的关闭按钮?我可以为这些琐碎的事情编写大量代码,但我讨厌把GUI弄得乱七八糟。事实上,你无法捕捉到这一点,Access直接在表上工作,当字段移动到另一个字段、记录或按钮而失去焦点时,每一个更改都已经被保存 事实上,与Excel相比,这是一个很大的优势
如果你真的想要一个类似Excel的行为,你需要处理一份表的副本和一些更新代码。你必须在更新事件之前使用
表单。下面是一个例子;但是,它确实会创建一条典型的警告消息:“此时无法保存此记录。Microsoft Access在尝试保存记录时可能遇到错误…”,具体取决于您的数据库设置。您可以使用下面的简单解决方法来避免显示该消息
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = True
'Or even better you can check certain fields here (If Then...)
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = True
End If
End Sub
这是我的代码,检查表单是否正在关闭或保存
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Not UsingSaveButton Then
If MsgBox("Abandon Data?", vbInformation + vbYesNo) = vbNo Then
Cancel = True
Else
DoCmd.RunCommand acCmdUndo
End If
End If
End Sub
我有一个布尔标志,在加载时设置为False,然后当使用“保存”按钮时,我将其设置为true以允许更新运行。
如果未设置标志,则他们将离开记录(通过转到其他记录或关闭表单),因此我询问他们是否确实要保存更改。
Cancel=True
如果有任何更改,将中止退出表单或移动到其他记录。
DoCmd.run命令acCmdUndo
撤消任何更改,因此不会保存这些更改。Sean给出了一个几乎正确的答案,但留下了一些空白
通常,表单的更新前是最重要的表单事件。这是您的最后一道防线,始终在保存记录之前运行,无论是什么提示保存(表单关闭、新记录、您自己的保存按钮、单击进入子表单等),尽管我偶尔会使用控件的BeforeUpdate
事件,只是为了让用户更快地获得错误消息,我编写的大部分验证代码在更新前的表单中运行。如果要确保某些控件不是空的,则必须使用此事件。对于所有情况,没有控制级别事件能够可靠地执行此操作。主要是因为如果控件从未获得焦点,则不会触发任何控件级事件<如果验证涉及多个字段,则代码>Form_BeforeUpdate
也是您将使用的事件。如果您正在使用任何其他控件或事件级别的事件,则是在浪费时间。你的“陷阱”周围总是有很多信息,你的表几乎肯定包含无效数据
关于OP的问题。如果您想强制人们使用您自己的保存按钮,并在他们不使用时提示他们,那么您需要一个表单级变量,正如Sean的建议所暗示的那样。唯一的区别是,您需要在表单的当前事件而不是打开事件中将其设置为False。您希望为每个新记录重置标志,而不仅仅是在表单打开时。然后在“保存按钮单击”事件中将其设置为True,然后使用DoCmd.RunCommand acCmdSaveRecord
强制保存记录
最后,在Form\u BeforeUpdate
事件中,检查变量的值
If bClose = False Then
If MsgBox("Do you want to save the changes?", vbYesNo) = vbNo Then
Cancel = True
If MsgBox("Do you want to discard the Changes?", vbYesNo) = vbYes Then
Me.Undo
End If
Exit Sub
End If
End If
**您可以将“退出”按钮与此代码一起使用**
Private Sub Button_Click()
If Me.Dirty = True Then
If MsgBox(" Save Change ", vbYesNo) = vbYes Then
Me.Dirty = False
Else
Me.Undo
End If
End If
DoCmd.Close acForm, "FormName"
End Sub
在“卸载时”事件的表单中添加以下代码
DoCmd.RunCommand acCmdUndo
DoCmd.Quit
当用户以任何方式关闭表单时,记录将不再保存。我一直认为绑定的countrol实际上链接到表单记录集属性的字段。这是一个错误的假设吗?@StevenDotNet,记录只有在执行保存、移动到其他(或新)记录或关闭表单后才会保存。这类似于必须调用RecordSet.Update()
才能应用更改。除了表单更新记录集,即使我不希望它更新记录集。我忘记了BeforeUpdate事件,但它不会在任何表单关闭事件之前触发吗?为了澄清,我只希望在用户单击表单关闭按钮时取消=true。您可以轻松禁用表单上的关闭(X)按钮(表单属性)。我仍然希望允许用户关闭表单,但需要通知他们所做的更改将被保存。如果他们能在关闭表单之前撤销更改,那就更好了。真是太烦人了,竟然没有BeforeUnload事件。这听起来真不错。我假设UsingSaveButton=False
在更新后进入表单
?我在保存时使用它。将UsingSaveButton=True置于开头,并在结尾将其设置为false(确保任何错误处理也会将值设置为false。在加载表单或当前事件时,将值设置为false这可能没有什么帮助,但这就是为什么使用未绑定表单很好。我这样看待它:对于绑定表单,您必须阻止任何不希望的更改,而对于未绑定表单,您只能提交您希望的更改,这取决于你喜欢从哪一方解决问题。然而,绑定形式可能很有用,但我实际上只在需要连续形式时才使用它们。从某种意义上说,这正是我想要的