2010-11-19 43 views
4

我们有一个MS Access 2007数据库,其中包含一个显示表格数据的简单表单。我们使用查找对话框(单击主页功能区上的双筒望远镜)来查找我们想要的记录。这可能会在特定情况下导致错误。使用查找对话框MS Access“更新或取消更新”错误

步骤来重现问题:

  1. 打开窗体。
  2. 打开查找对话框。
  3. 在记录中编辑一些字段。 该记录现在处于更新模式 (您将在行的 “排水沟”区域看到铅笔)。
  4. 不保存记录,点击 ALREADY打开查找对话框。
  5. 搜索不能找到的记录 。
  6. 再次单击窗体。记录 仍处于编辑模式(即铅笔仍显示 )。尝试保存 或编辑其他字段。
  7. 此消息框将显示 “更新或取消更新没有 添加新建或编辑”。您可以单击确定或 帮助按钮。

点击帮助按钮显示:

尝试调用Update或CancelUpdate或试图以更新记录现场 而无需先调用的AddNew或编辑。 (Error 3020)

在将Microsoft Access数据库引擎数据库中的 数据写入记录之前,您调用了更新或 CancelUpdate方法,但未使用AddNew或Edit方法。

在ODBCDirect数据库上,当您尝试在没有首先调用AddNew或Edit的情况下将数据 写入记录时,就会发生此错误。

我们已经在没有VBA代码的新数据库中重现了这一点。所以这个问题完全在MS Access中,你应该能够很容易地重现它。

如果您在查找之前保存记录,则问题不会发生。不幸的是,当记录仍处于编辑模式时,我们有用户正在查找。

我们尝试设置表单级别,数据字段级别和Access应用程序级别事件和错误处理。没有什么可以检测或捕捉到这种情况VBA无法检测“查找”对话框是否处于活动状态。

有没有人有任何想法来防止错误或在发现之前保存记录的方法?我们现在最好的想法是创建AutoHotkey或AutoIt脚本,等待查找对话框获得焦点。然后,我们将发送Ctrl + S来保存当前记录以强制保存。

+1

是自定义功能区更改为查找功能适合您的选项(http://office.microsoft.com/en-us/access-help/customize-the-ribbon-HA010211415.aspx)? – Fionnuala 2010-11-19 20:09:10

+0

Ctrl-S不保存记录。它保存了当前UI对象的设计(在这种情况下,您正在编辑的表单)。 – 2010-11-21 22:19:56

+2

正如@Remou所建议的那样,我会用打开前保存的缺省FIND快捷方式替换,或者编写我自己的查找代码。一般来说,我会说依靠UI的find函数表示一个欠发达的应用程序用户界面。 – 2010-11-21 22:20:55

回答

1

我们想出的解决方法是编写一个AutoIt脚本,它可以监视查找对话框何时获得焦点并保存记录(如果已更改)。

我们不希望将脚本与数据库分开分发,因此该脚本作为Blob添加到数据库表中。数据库的AutoExec宏运行一些VBA代码,将脚本从Blob表中取出并启动脚本。

当脚本检测到“查找”对话框具有焦点时,该脚本在数据库中运行VBA宏。宏检查当前记录是否脏。如果脏,宏将强制保存。此外,AutoIt脚本在数据库关闭时停止。

这是非常尴尬,但它的作品。

+4

这太可怕了。我会设计我自己的FIND,并在我想到任何可怕的东西之前,从工具栏/功能区中消除双筒望远镜。 – 2011-02-08 05:25:48

+0

我同意使用AutoIt脚本是一种破解。但是我们认为这是让我们的内部用户使用数据库的最快捷方式。如果我们提供客户产品,我们会尝试更加优化的方法。我们认为重新创建查找对话框的功能需要付出很多努力,因为对话框有一些有趣的功能(如确定哪个表单域具有焦点)。 – 2011-02-10 14:09:57

+0

确定焦点所在的字段是完全微不足道的,即在打开自定义查找表单之前调用的“Screen.ActiveControl”。 – 2011-02-12 00:03:47

1

我建议您找到MS-Access 2007中引入的错误。但是,我无法在我的副本上复制该错误。我想我们都是最新的补丁,所以也许会有更微妙的事情发生。

如果你想迫使记录要保存,使用的下面的一个 - 不是CTRL-S

  • if me.dirty then Me.Dirty = false ''(n.b. often the preferred method)

  • Docmd.RunCommand acCmdSaveRecord

  • DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70 ''(n.b. deprecated)

根据我的理解,问题在于,如果他们在“查找”已打开后编辑窗体,然后执行“查找”,则会显示错误。

我想尝试以下两种情况之一:

  1. 找到一个方法来关闭内置的查找表,并且这样做,只要你让当前记录脏(脏)
  2. 添加您自己“查找”按钮(不打开内置的查找表单),并隐藏功能区上的按钮。
+0

DoMenuItem自2000年起至今已弃用.DoCmd.RunCommand是替代方案,但为了保存记录,通常建议检查'If Me.Dirty Then Me.Dirty = False'。 – Fionnuala 2011-02-07 15:34:17

+0

@Remou - 1)它似乎仍然有效2)我假设2007年的向导会产生比当时(2003年)我可用的版本更好的代码;因此我的“或wterter线”(刚刚尝试过......宏...呃)。 3)我不知道'Me.Dirty = False'也有保存记录的副作用(它肯定没有在帮助文件中列出)。 4)采取了一些措施,我学到了一些新的东西,并且将来会使用它。 – BIBD 2011-02-08 04:35:02

+0

我屈服于诱惑,对不起,但如果你想编辑你的答案,我会扭转投票。 – Fionnuala 2011-02-08 09:44:00

1

@ CodeSlave的回答提出了一种可能性,对我说:

而不是简单地从工具栏/色带取出望远镜,而不是改变什么双筒望远镜做。也就是说,让它调用代码保存当前记录,如果它很脏,然后启动FIND对话框。

现在,需要一些代码来检查表单是否打开,并且它有一个记录源(如果没有记录源,则测试.Dirty属性错误),并且一个字段具有焦点,但是所有这些都是可行的。可能很多(除了最后一个)将通过仅在加载表单时显示工具栏/功能区或在窗体打开时编辑默认工具栏/功能区来处理。

但是这比使用进程外解决方案要疯狂得多,而且你的用户不会知道任何区别。

+0

我认为问题在于编辑前查找对话框已经打开。因此,在打开对话框时插入保存将无法解决问题。 – BIBD 2011-02-08 22:26:08

+0

好的,所以您可以锁定窗体上的控件,或者将其设置为不可编辑,直到查找对话框关闭。哎呀。不知道你是如何发现它已经关闭的......所以,我想你只剩下滚动你自己的查找对话框来替换内置的Access(我从来没有真正喜欢过它,我自己)。 – 2011-02-09 03:36:40