We have an MS Access 2007 database with a simple form displaying table data. We use the Find dialog (click the binoculars on the Home ribbon) to locate records we want. This can cause an error under specific circumstances.
Steps to reproduce the problem:
- Open the form.
- Open the find dialog.
- Edit some field within the record.
The record is now in update mode
(you’ll see the pencil in row’s
“gutter” area). - Without saving the record, click on
the ALREADY open Find dialog. - Search for a record that can’t be
found. - Click on the form again. The record
is still in edit mode (i.e. the
pencil still shows). Attempt a save
or edit some other field. - This message box will display
“Update or CancelUpdate without
AddNew or Edit.” You can click OK or
Help buttons.
Clicking the Help button shows:
You tried to call Update or CancelUpdate or attempted to update a Field
in a recordset without first calling AddNew or Edit. (Error 3020)On a Microsoft Access database engine database, you called the Update or
CancelUpdate method but did not use the AddNew or Edit method before writing
data to a record.On an ODBCDirect database, this error occurs when you attempt to write data
to a record without first calling AddNew or Edit.
We’ve reproduced this in a new database where there is no VBA code. So the problem is solely within MS Access, and you should be able to reproduce it easily.
If you save the record before doing the find, the problem doesn’t happen. Unfortunately, we have users doing a find while the record is still in edit mode.
We’ve tried setting up form-level, data-field-level, and Access application level events and error handling. Nothing can detect or catch this situation. There is no way within VBA to detect if the Find dialog is active.
Does anyone have any ideas for preventing the error or a way to save the record before the find occurs? Our best thought right now is to create an AutoHotkey or AutoIt script that waits for the Find dialog to have focus. We’ll then send a Ctrl+S to save the current record to force a save.
The hack, work-around we came up with was to write an AutoIt script which can watch for when the Find dialog gains focus and save the record if it has changed.
We didn’t want to distribute the script separately from the database, so the the script was added to a database table as a Blob. The database’s AutoExec macro runs some VBA code that pulls the script out of the Blob table and starts the script.
When the script detects that the Find dialog has focus, the script runs a VBA macro in the database. The macro checks to see if the current record is dirty. If dirty, the macro forces a save. Also, the AutoIt script is stopped when the database is closed.
This is all pretty awkward, but it works.