Unexpected Form_Undo event (1 Viewer)

GK in the UK

Registered User.
Local time
Today, 22:12
Joined
Dec 20, 2017
Messages
274
Scenario:

I have validation in BeforeUpdate which cancels the save.

If I enter invalid data on a form, and try to save the record with DoCmd.RunCommand acCmdSaveRecord, my error trap fires and I pop up a message.

In testing, I'm finding that when I try to close the form with the 'X', I get my custom error message, but Form_Undo is also called.

So I lose ALL the data input on the form when I attempt to close with the 'X'.

If the data is valid, the data is saved when I close with the 'X'.

I wasn't expecting this behaviour. Is this how it is or is it something in my code that's undoing the form ? (If it is I haven't found it yet)

I'm aware that I can disable the 'X' for the form and I may do that, but I want to prevent the closure of a form if the user tries to close Access, preferably, without discarding all the data on the form.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 14:12
Joined
Oct 29, 2018
Messages
21,454
Hi. I suspect you don't have warning turned on in your database, if you're not getting a confirmation message before the form closes. If you are getting a message, then I think you'll see why this is a normal behavior.
 

GK in the UK

Registered User.
Local time
Today, 22:12
Joined
Dec 20, 2017
Messages
274
I just looked in Options, Client Settings
Record Changes, Document Deletions, Action queries. all ticked. Is there something else to check ?
 

theDBguy

I’m here to help
Staff member
Local time
Today, 14:12
Joined
Oct 29, 2018
Messages
21,454
I just looked in Options, Client Settings
Record Changes, Document Deletions, Action queries. all ticked. Is there something else to check ?
You could check your code to see if you are using SetWarnings False.
 

GK in the UK

Registered User.
Local time
Today, 22:12
Joined
Dec 20, 2017
Messages
274
I have used SetWarnings False in one place in my app but nothing to do with this form.

I commented out my Form_Undo sub, and checked that the Event reference was gone in form design.

Access still does an Undo if I try to close the form with the 'X'. It doesn't undo when I try to save with a command button. It seems like if I have Cancel = True in BeforeUpdate, it forces an Undo if I close with the X.

Can't get this one figured out.
When I close the form with the 'X' with invalid data (so BeforeUpdate has been Cancelled) Form_Error fires, AFTER Before_Update. In Form_Error, dirty=true. Form_Error is fired ONLY when I attempt to close with the 'X'. But there is nothing in Form_Error to Undo the form.

The next event that fires after Form_Error, is Form_Unload, which I cancel. In Form_Unload, dirty has become false. I've lost all the data.

OK I think the answer is here (need to do more testing):
http://www.justskins.com/forums/not-prompted-for-saving-105202.html
Note that the explicit save (setting Dirty to false) is necessary due to a
bug in Access that just silently discards your edits and closes the form
with no warning if there is any reason why the record can't be saved (e.g. a
validation rule is not meet, or a required field is not present).
--
Allen Browne - Microsoft MVP. Perth, Western Australia.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 14:12
Joined
Oct 29, 2018
Messages
21,454
I have used SetWarnings False in one place in my app but nothing to do with this form.

I commented out my Form_Undo sub, and checked that the Event reference was gone in form design.

Access still does an Undo if I try to close the form with the 'X'. It doesn't undo when I try to save with a command button. It seems like if I have Cancel = True in BeforeUpdate, it forces an Undo if I close with the X.

Can't get this one figured out.
When I close the form with the 'X' with invalid data (so BeforeUpdate has been Cancelled) Form_Error fires, AFTER Before_Update. In Form_Error, dirty=true. Form_Error is fired ONLY when I attempt to close with the 'X'. But there is nothing in Form_Error to Undo the form.

The next event that fires after Form_Error, is Form_Unload, which I cancel. In Form_Unload, dirty has become false. I've lost all the data.

OK I think the answer is here (need to do more testing):
http://www.justskins.com/forums/not-prompted-for-saving-105202.html
Note that the explicit save (setting Dirty to false) is necessary due to a
bug in Access that just silently discards your edits and closes the form
with no warning if there is any reason why the record can't be saved (e.g. a
validation rule is not meet, or a required field is not present).
--
Allen Browne - Microsoft MVP. Perth, Western Australia.
Just FYI, once you use SetWarnings False anywhere in your app, it affects the entire program - not just the place (form, etc.) where you used it.

Clicking on the X to close the form tells Access you want to force a close. So, when the data is changed but the BeforeUpdate cancels the save, then Access has to undo the changes before it can close the form.
 

GK in the UK

Registered User.
Local time
Today, 22:12
Joined
Dec 20, 2017
Messages
274
OK thank you. So you're saying it's by design, then, if it's not a bug. I did change my save code to Me.Dirty = false (per my link above) and it still discards the edits.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 14:12
Joined
Oct 29, 2018
Messages
21,454
OK thank you. So you're saying it's by design, then, if it's not a bug. I did change my save code to Me.Dirty = false (per my link above) and it still discards the edits.
That's because it has invalid data, which you have designed to be discarded.
 

Micron

AWF VIP
Local time
Today, 17:12
Joined
Oct 20, 2018
Messages
3,478
I don't think you've posted enough code to reveal the issue, which is probably just the flow/logic you've used. Form_Undo sounds like a procedure you have, which may be getting called when it shouldn't. I say that because the syntax in a form module to discard changes is Me.Undo, not Form_Undo.
 

GK in the UK

Registered User.
Local time
Today, 22:12
Joined
Dec 20, 2017
Messages
274
DbGuy, now you've explained it like that it makes perfect sense. Actually Pat explained this to me over 2 years ago and I'd completely forgotten, I keep putting the project away and returning to it. Maybe lockdown will focus my mind a bit.

Micron, as far as I understand it, Me.Undo is the command to undo the form, but when you do that, Form_Undo fires.

So I have my 'Undo' code (because I have some unbound fields that need 'undoing') in Form_Undo.

I *think* I'm right in saying, Form_Undo also fires when the user uses the built-in Access Ctrl-Z. So to allow for that, I put 'Undo' code in Form_Undo, not in the Command Undo sub. There has to be an Event call for Form_Undo in the form, of course.

I couldn't figure out why Form_Undo was firing on press of the 'X' button but DbGuy explains it. I think what Access is saying is, if I absolutely MUST close this form, and the data isn't valid, I must revert to the Last Known Good.

I was also Cancelling the Unload, which left me with an open form but with the unsaved form data discarded, which I didn't really want. I had an extra 'logic trap' if you like, in that I had to validate the child lines before close. The child lines absolutely must balance to 0, so any number of them can be individually correct, but the sum of them must be 0. So in that case, Access doesn't know or care that the child lines don't follow the business rules.

I also discovered that attempting to close the form with the 'X' with invalid data fires Form_Error, so as well as error traps on both the Save and Close Commands in the module sub's I have to have an error trap on 2169 in Form_Error.

It's somewhat convoluted but I seem to have code that covers all eventualities. It's an enhancement of Pat's suggestion way back when to have a module variable bAllowClose. So far I haven't been able to break it. I'll have to live with the 'Undo', after all, the user shouldn't really be using the 'X' to close the form.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 14:12
Joined
Oct 29, 2018
Messages
21,454
DbGuy, now you've explained it like that it makes perfect sense. Actually Pat explained this to me over 2 years ago and I'd completely forgotten, I keep putting the project away and returning to it. Maybe lockdown will focus my mind a bit.

Micron, as far as I understand it, Me.Undo is the command to undo the form, but when you do that, Form_Undo fires.

So I have my 'Undo' code (because I have some unbound fields that need 'undoing') in Form_Undo.

I *think* I'm right in saying, Form_Undo also fires when the user uses the built-in Access Ctrl-Z. So to allow for that, I put 'Undo' code in Form_Undo, not in the Command Undo sub. There has to be an Event call for Form_Undo in the form, of course.

I couldn't figure out why Form_Undo was firing on press of the 'X' button but DbGuy explains it. I think what Access is saying is, if I absolutely MUST close this form, and the data isn't valid, I must revert to the Last Known Good.

I was also Cancelling the Unload, which left me with an open form but with the unsaved form data discarded, which I didn't really want. I had an extra 'logic trap' if you like, in that I had to validate the child lines before close. The child lines absolutely must balance to 0, so any number of them can be individually correct, but the sum of them must be 0. So in that case, Access doesn't know or care that the child lines don't follow the business rules.

I also discovered that attempting to close the form with the 'X' with invalid data fires Form_Error, so as well as error traps on both the Save and Close Commands in the module sub's I have to have an error trap on 2169 in Form_Error.

It's somewhat convoluted but I seem to have code that covers all eventualities. It's an enhancement of Pat's suggestion way back when to have a module variable bAllowClose. So far I haven't been able to break it. I'll have to live with the 'Undo', after all, the user shouldn't really be using the 'X' to close the form.
Hi. Glad to hear you got it sorted out. If the form and code starts to get "convoluted," maybe you could consider using unbound forms next time. Nothing gets saved unless you specify it; otherwise, everything is discarded. Cheers!
 

Users who are viewing this thread

Top Bottom