How to prevent Esc key to reset fields ??

M

Michel S.

Hi !

I have a form with many subforms.

Each subform can contain up to 8 fields.

However, if I press "Esc" on any field, all the fields of the subform
containing that field are reset to their original values.

Each subform as well as the main form contains a command button with
its Cancel property set to True.

In addition, in the main form as well as in the subforms, the
KeyPreview is enabled and each contain the following "KeyPress" event
code : If KeyAscii = 27 then KeyAscii = 0

What am I missing ??

Thanks
 
A

Allen Browne

From memory, I doubt the Esc key triggers the KeyPress event. Try KeyDown
instead.

There's a bit of a Catch 22 with the approach you are taking. If I was in a
text box bound to a required field, and tried to click your Cancel button,
Access would validate the field before letting me out of the box. So, if I
had entered something and backspaced it out, I would now be stuck in the
control, unable to even get to your Cancel button.

I'm not sure, but the fact that you are destroying the Esc keystroke may
mean that setting the button's Cancel property to Yes has no effect.

Also, I'm not clear what would be the purpose of disallowing the undo, and
yet trying to direct it into the Click event of a command button. Couldn't
you just use the Undo event of the form to handle whatever you want to do?
 
M

Michel S.

Allen,

Thanks for your reply.

To make a long story short, the situation you are finding strange it's
because I have successively implemented all the methods I know for
cancelling the esc key, the first one being to use a button with the
"Cancel" property set to true, but seeing it wasn't working, I used
another one, then a third one, etc.. but without results so far.

What I'm trying to do is at least to "intercept" the Esc keypress and
confirm with the user that he really wants to reset all fields entered
so far in the subform.

Hope this looks less strange now ! ;o)

Michel

Allen Browne avait énoncé :
 
A

Allen Browne

Why not just work with the events Access provides for you?

Assuming Access 2000 or later:

Private Sub Form_Undo(Cancel As Integer)
If MsgBox("Undo all changes to this record?", vbYesNo, "Confirm
undo") <> vbYes Then
Cancel = True
End If
End Sub
 
A

Albert D. Kallal

I have a rather large number of applications in which the Esc key actually
means save and close!!!

You can trap the Esc key by simply using the keydown event....

If KeyCode = 27 then
KeyCode = 0
end if


The above will effective disable the esc key.

Don't forget to set the forms key-preview = yes
(and, you need the above code in EACH of the sub-forms, with each set
keypreview = yes.)
 
M

Michel S.

Just because :

1) I have also to support Access 97 applications ant then reluctant to
have two sets of utilities;

2) I heard that some events (like Undo and Lost Focus) aren't always
fired when they should;

3) Experienced that writing Me.Undo in code doesn't fire the Undo event
at all;

4) Still doesn't understand why the old "invisible button set to
Cancel" doesn't work in the case I was talking about.

Thanks


Allen Browne a couché sur son écran :
 
M

Michel S.

I'd prefer "Save and close" to "discard all without warning and close".
But actually, I get none of these.

What I want is "reset the current field's original value" only - not
the entire record.


The Keycode = 0 trick works, but doesn't meet my needs; I dont want to
disable the Esc key, but be aware of it and offer the user options or
react accordingly.

As I answered to Allen, I'm still puzzled on why the "Button" control
set to "cancel" doesn't work, even if I set one in all subforms and in
the main form.

Thanks..


Albert D. Kallal a utilisé son clavier pour écrire :
 
D

Dirk Goldgar

Michel S. said:
Just because :

1) I have also to support Access 97 applications ant then reluctant to
have two sets of utilities;

2) I heard that some events (like Undo and Lost Focus) aren't always
fired when they should;

What have you heard? I've never heard of any event not firing when it's
supposed to. There may be some discussion about when it's supposed to,
of course.
3) Experienced that writing Me.Undo in code doesn't fire the Undo
event at all;

I just tried it in a simple test, and the event fired. What were the
circumstances of your experience?
4) Still doesn't understand why the old "invisible button set to
Cancel" doesn't work in the case I was talking about.

Because it's invisible. I wouldn't expect an invisible button to fire.
I just checked, and the Cancel button fires when it's visible, and not
when it's invisible.
 
A

Allen Browne

Michel, your original post indicated you included the line:
If KeyAscii = 27 then KeyAscii = 0

I don't understand why you expect the keystroke to still work after you
destroyed it.
 
A

Allen Browne

Responses embedded.

--
Allen Browne - Microsoft MVP. Perth, Western Australia.

Reply to group, rather than allenbrowne at mvps dot org.

Michel S. said:
Just because :

1) I have also to support Access 97 applications ant then reluctant to
have two sets of utilities;

Makes sense if this particular app is still being used in A97 machines.
2) I heard that some events (like Undo and Lost Focus) aren't always fired
when they should;

Misinformed. The Undo event of the form does fire reliably in A2000 and
later.

The kb article that provided a faux-undo event for Access 97 was unreliable,
so perhaps that was the source of the rumour.
3) Experienced that writing Me.Undo in code doesn't fire the Undo event
event at all;

I find that hard to believe. It might be so if you attempted this in an
event that is part of a chain of events where the undo is not feasible, such
as in the KeyDown of a bound control, when you don't destroy the keystroke,
so that there is now a whole sequence of events set in motion (the control's
KeyPress, KeyUp, Change, BeforeUpdate, AfterUpdate, Exit, Lost Focus, Got
Focus of the next control, and potentially the events of the form itself.)
Something in this avalanche of events could cancel the undo, or even dirty
the form again. But the Undo is reliable.

Or perhaps you heard that Me.Undo does not achieve the same result as
RunCommand acCmdUndo or DoMenuItem. In later versions, Access can (wrongly
in my view) apply the undo to previously saved records - a real bugbear!
Me.Undo does not have this problem.

4) Still doesn't understand why the old "invisible button set to Cancel"
doesn't work in the case I was talking about.

You cancelled the keystroke, and still expect it to work?
 
M

Michel S.

Allen, as I told you in a previous post, the first thing I tried was
the command button *only* and it wasn't working. I added the KeyPress
trap only after that. Actually, the KeyAscii = 0 was the *last*
thing I tried; it's sure I didn't expect the previous tries to work
when I was trying another one.

Michel

Allen Browne avait prétendu :
 
M

Michel S.

Dirk Goldgar avait énoncé :
There may be some discussion about when it's supposed to,
of course.

Its definitely a better way to say what I intended to.. ;o)
Because it's invisible. I wouldn't expect an invisible button to fire.
I just checked, and the Cancel button fires when it's visible, and not
when it's invisible.

By invisible, I meant "Transparent". The Visible property was true.

Is this what you experienced ?


Thanks again
 
A

Albert D. Kallal

I'd prefer "Save and close" to "discard all without warning and close".
But actually, I get none of these.

What I want is "reset the current field's original value" only - not the
entire record.

The Keycode = 0 trick works, but doesn't meet my needs; I dont want to
disable the Esc key, but be aware of it and offer the user options or
react accordingly.

Oh...ok, nice to know!!!

Of course, after we trap/destroy the esckey, then it will be disabled.

Normally, the first esc key will un-do changes to the CURRENT field. If you
hit esc a 2nd time, it will un-do the whole record...

the problem is of course if you made modifications to other fields/(well
controls), and moved around in he form, and are on a field with NO changes
made, then the first esc key will un-do all changes.

So, how to trap esc key is possible, but you also need to know if the
current control that has the focus has been changed or not....

Further, you also need to know if a control has the focus when you hit esc.
Note that in code you can simulate the esc key as follows

me.undo

Hum.....I not sure if you can do this. I would perhaps suggest that you
disable esc key, and have users go edit->undo
(note how it shows
a) - undo typing
or
b) undo

So, the context of the edit menu does change for the two cases I have
explained above.

You could perhaps cobble together some code in the keydown event that grabs
the current control (screen.activeContorl), and checks the last modified
(oldvalue) setting. So, you likely can code this, I just not 100% sure on
the test for the current field having been modified. If the "oldvalue"
setting works, then you (likey) can code this to make Esc ONLY undo the
current control, and not the whole form.
 
M

Michel S.

Albert D. Kallal avait énoncé :
Normally, the first esc key will un-do changes to the CURRENT field. If you
hit esc a 2nd time, it will un-do the whole record...

the problem is of course if you made modifications to other fields/(well
controls), and moved around in he form, and are on a field with NO changes
made, then the first esc key will un-do all changes.

So, how to trap esc key is possible, but you also need to know if the current
control that has the focus has been changed or not....

Further, you also need to know if a control has the focus when you hit esc.
Note that in code you can simulate the esc key as follows

me.undo

Hum.....I not sure if you can do this. I would perhaps suggest that you
disable esc key, and have users go edit->undo
(note how it shows
a) - undo typing
or
b) undo

So, the context of the edit menu does change for the two cases I have
explained above.

You could perhaps cobble together some code in the keydown event that grabs
the current control (screen.activeContorl), and checks the last modified
(oldvalue) setting. So, you likely can code this, I just not 100% sure on the
test for the current field having been modified. If the "oldvalue" setting
works, then you (likey) can code this to make Esc ONLY undo the current
control, and not the whole form.

Thanks for your input..

Obviously there's no simple solution ! But your suggestion
implemented on the form's undo (or keydown) could do the trick.

Before reading your answer, I made some tests with a simple subform
containing two bound textboxes. If I change one of the control's value
then hit "Esc", I noted that :
- the control's Keypress event enters with the value 27 (just to make
everybody sure that the form's KeyAscii = 0 is not in effect);
- the control's Undo event don't fire;
- the control's value is resetted to it's original value *before*
entering the Keypress event, which prevent me to catch it there.

If I enter a value in the first textbox then a value in the second then
hit Esc, both values are resetted and the controls Undo event dont
fire.

I didn't put code at form level, but hopefully the controls Undo event
will fire even if the event is not monitored at the form level ?

And if the current control is dirty, doesn't it make sense to fire it's
undo event before the form's one ?

What am I missing here ?


Thanks again..
 
D

dbahooker

Maybe you should stop ****ing using an obsolete version?

of course it has bugs.

if Access 97 was BETTER at ANYTHING we would all still be using it.

Companies that are too fat and lazy to migrate to the latest version
should be shot.
And Access 97 doesnt even support ADP applications.

ADP makes MDB 100% obsolete

-Aaron
 
A

Albert D. Kallal

Obviously there's no simple solution ! But your suggestion implemented
on the form's undo (or keydown) could do the trick.

Actually, I said there *might* be a simple solution. that would involve
KNOWING that the current control have been changed..and as I said if we
can't use the "oldvalue", then we are in trouble. If we can..then the
solution will yield itself, and should not be difficult..
(and, as you will see, this issue of oldvalue does NOT matter, and THEREFORE
the solution is easy!!)
Before reading your answer, I made some tests with a simple subform
containing two bound textboxes. If I change one of the control's value
then hit "Esc", I noted that :
- the control's Keypress event enters with the value 27 (just to make
everybody sure that the form's KeyAscii = 0 is not in effect);
- the control's Undo event don't fire;

Of course!...the instant we start grabbing the keyproess, then those events
are toast, and will not fire. (at least in the case of the Esc key anyway).

Remember, the undo event for a control will ONLY fire if you use Esc key, or
the un-do button the tool bar, but does NOT fire if you use the edit->undo
typing. further, the event is ONLY of use for a single control that has the
focus.

If I enter a value in the first textbox then a value in the second then
hit Esc, both values are resetted and the controls Undo event dont fire.

Yes..the above makes sense. (because we are trapping the esc key, those
events will not fire). further, if you had 50 controls on a screen, you
don't expect 50 undo evens to fire???? (hint: only the control that has the
focus will fire the undo event).

Since each control does have a undo event, and there is a cancel option. So,
in theory, we could add code to each text box, combo box etc..on a
form....such as:

Private Sub Description_Undo(Cancel As Integer)

Cancel = True

End Sub

The problem with the above is that we would have to code this for each
button..and, that not a solution at all. In fact, I did not even suggest the
above, since I do NOT consider it a reasonable solution (but, that was
always a possible fall back position here...and I had assumed this was
obvious).

So, a few things:

We are going to stick to using the keydown event, as it is the best (and
first) event to trap keystrokes.
(so, don't bother with keyspress event)

We really don't want to have to place code in each text box as above


The code that should work a form is as follows:

Keydown event for the FORM...and make SURE that key preview is set = yes....



If KeyCode = vbKeyEscape Then

KeyCode = 0 ' kill the key

On Error Resume Next

Screen.ActiveControl.Undo

End If


That is all we need. In thinking about the above, it really don't matter if
we execute a control.undo command more then once (that is why I talked about
needing to CHECK if the control has been modified...it turns out we don't
have to check). The above makes this easy as pie....
 
M

Michel S.

Thanks Albert,

I appreciate your input - and actually your Form level
ActiveConrol.Undo solution is exactly what I'm looking for, because
usually, at least in my case and in the case of many users I know, when
I use "Esc" to revert (or cancel) a control (or cell in Excel), it is
precisely the control (cell) I'm currently typing in. (I compare to
Excel because that's the interface most of my applications users are
accustomed to).


But there are a couple of questions remaining in my mind - something
unclear, maybe you can help me clarify.

First, when you say :
Of course!...the instant we start grabbing the keyproess, then those events
are toast, and will not fire. (at least in the case of the Esc key anyway).

I don't get it.. Do you mean because I have a KeyPress event procedure
for a spcefific control, then the Esc key operates it's way without a
way to intercept it (other than just cancelling it) ?

Remember the test in my previous post : there was no form's level
keystroke grabbing of any kind and my sample form included only two
textboxes, each containing an Undo and Keypress event procedures.
Upon pressing the Esc key, both controls were resetted *before*
entering the Keypress routine and the Undo event never fired.


In addition, since the current (ie: active, focused) texbox was dirty
when I hit the Esc key, this also seems to be incoherent with this
previous quote from you:
Normally, the first esc key will un-do changes to the CURRENT field.
If you hit esc a 2nd time, it will un-do the whole record...

I don't mean you were incoherent ;o) on the contrary, it's the program
behavior I do not understand -- because what you said is also what I
expected and it is what made me fiddle with the code and start this
thread in the first place.

Unless you made a distinction between fields/records vs controle/forms
?
Remember, the undo event for a control will ONLY fire if you use Esc key, or
the un-do button the tool bar, but does NOT fire if you use the edit->undo
typing. further, the event is ONLY of use for a single control that has the
focus.

I'm only interested in the Esc key. If a user goes to the menu to
select "Edit -> Undo", I guess it's not "accidental". lol

(hint: only the control that has the focus will fire the undo event).

Thanks for the hint, but my orginal question is exaclty why it doesn't
fire in my case ?
Since each control does have a undo event, and there is a cancel option. So,
in theory, we could add code to each text box, combo box etc..on a
form....such as:

Private Sub Description_Undo(Cancel As Integer)

Cancel = True

End Sub

The problem with the above is that we would have to code this for each
button..and, that not a solution at all. In fact, I did not even suggest the
above, since I do NOT consider it a reasonable solution (but, that was always
a possible fall back position here...and I had assumed this was obvious).

I can think a "reasonable" way to do this : using a class module where
you define "WithEvents" a textbox control and write generic undo (an
all other events you wish) code. In the form Load event, you set your
controls as members of that class and you're done.. ;-)
The above makes this easy as pie....

Sure, and *you* said it ! :)

Michel
 
A

Albert D. Kallal

Of course!...the instant we start grabbing the keyproess, then those
I don't get it.. Do you mean because I have a KeyPress event procedure
for a spcefific control, then the Esc key operates it's way without a way
to intercept it (other than just cancelling it) ?

When I was referring to "grabbing" keypress, I was assuming the keydown
event, and also assuming setting the keyvalue = 0.

So, if you do pre-process the key value at the form level (key down), and
kill it (keyvalue = 0), then you have compete override of the esc key
behaviours.
Remember the test in my previous post : there was no form's level
keystroke grabbing of any kind and my sample form included only two
textboxes, each containing an Undo and Keypress event procedures. Upon
pressing the Esc key, both controls were resetted *before* entering the
Keypress routine and the Undo event never fired.

Hum...., the undo event SHOULD fire for ONLY the control that has the focus
(and ONLY fires if you made changes to the text box that has the focus).
Both controls should not be un-doing. (you should have to hit esc two
times). However if you NOT MADE modifications to the text control that you
just cursored into, then yes..the first Esc will UNDO ALL CHANGES. Further,
the undo event for that control will NOT fire. This is expected, and the way
it normally works.

So, to clear up

Esc will undo changes to the current text box, but if not make
changes..then it undo the whole form...

if you edit text1, text2, and now moving into text3

At this point, if you hit esc, then all changes will be un-done, and no
undo event for the controls will fire. So, you can move to ANY field on the
form, and single ESC key will UNDO ALL changes, and the contorl(S) undo
event will NOT fire. So, the undo event for the control will ONLY fire if
you made changes to that text box and NOT MOVED off of the text box yet.

So, yes...I think that is normal. If you are telling me that after
editing/changing the one text box, and then hitting esc undoes all
fields...that not normal...
I don't mean you were incoherent ;o) on the contrary, it's the program
behavior I do not understand -- because what you said is also what I
expected and it is what made me fiddle with the code and start this thread
in the first place.

Yes, but I suppose I should have added that you have to made changes to the
text box (I think leaving this out was a cause for consufing...and I should
have relizaed this). So, a single esc will often undo everything, and, no
undo event will fire unless the contorl that has focus has been actually
changed...
Thanks for the hint, but my orginal question is exaclty why it doesn't
fire in my case ?

answer = it only fires if you made changes to the control..if you moved off
the control...too late, and no undo event...
I can think a "reasonable" way to do this : using a class module where
you define "WithEvents" a textbox control and write generic undo (an all
other events you wish) code. In the form Load event, you set your
controls as members of that class and you're done.. ;-)

Yes...hum...sure, that is a another way to skin this cat! The code to set
all the members to the class object is still a bit of code...

Any hows, .....it turns out the simple keydown code does work for us
anyway....
 
M

Michel S.

Albert D. Kallal a utilisé son clavier pour écrire :
If you are telling me that after
editing/changing the one text box, and then hitting esc undoes all
fields...that not normal...

That's exactly what I'm telling you. To requote myself : "the current
(ie: active, focused) texbox was dirty when I hit the Esc key".

In other words, I placed the cursor on text1, made changes, moved to
text2 start making changes, pressed Esc while still in text2, both
controls were resetted, no Undo fired.

And I can't beleive this happens because a Keypress event procedure at
the control level only exists (I mean : it doesn't even process the Esc
key - I just set a breakpoint at the procedure start and saw that the
controls were already changed when the execution reached that
breakpoint ).
I suppose I should have added that you have to made changes to the
text box (I think leaving this out was a cause for consufing...and I should
have relizaed this).

Don't worry, it was crystal clear to me from the beginning. And you
did specify it too in one of your replies.

Then, given all this, we agree that it's not normal.


Yes...hum...sure, that is a another way to skin this cat! The code to set
all the members to the class object is still a bit of code...
Actually only 3 lines. ;-)

Any hows, .....it turns out the simple keydown code does work for us
anyway....

Right. :)

Thanks again !
 
D

dbahooker

dude I still think that the ESC key is the best feature ever.

why is it that you don't think that your end users are capable of
knowing when to press this?

are you using unbound forms or something?

Save your values more often; not 'disable the esc key'

-Aaron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top