Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 防止关闭按钮在MS Access中保存记录_Vba_Ms Access 2007 - Fatal编程技术网

Vba 防止关闭按钮在MS Access中保存记录

Vba 防止关闭按钮在MS Access中保存记录,vba,ms-access-2007,Vba,Ms Access 2007,在Microsoft Access窗体中,只要当前记录发生更改,绑定控件中的任何更改都会以静默方式保存到数据库表中。这很好,但我不希望在用户关闭表单时发生这种情况,因为这与许多人的预期正好相反 最好的例子是,当您试图关闭包含未保存更改的excel文件时,它会询问是否应放弃更改。这正是我试图在Access中实现的,但在VBA中找不到任何方法捕获close按钮的事件 表单的卸载事件是当有人单击关闭按钮时触发的第一个事件,但此时更改已写入数据库 这是可能的,还是我必须创建自己的关闭按钮?我可以为这些琐

在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这可能没有什么帮助,但这就是为什么使用未绑定表单很好。我这样看待它:对于绑定表单,您必须阻止任何不希望的更改,而对于未绑定表单,您只能提交您希望的更改,这取决于你喜欢从哪一方解决问题。然而,绑定形式可能很有用,但我实际上只在需要连续形式时才使用它们。从某种意义上说,这正是我想要的