Make event fire after undo

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

How can I get an event to fire after the undo of a control?

I need to use the original value of the control in running another Sub after
undoing the control, but the value does not revert until after the Undo event
is complete. I cannot simply use the ControlName.OldValue because I run the
same Sub (using the reference to this and other control names) in several
other places in this module.
 
How does that Sub know what the value of the control is, regardless of
whether it's the original or current value? You'll need to tell us more
info... I'm not convinced yet that you cannot use the OldValue value,
especially if you pass the control object as an argument to the subroutine
itself.

Which version of ACCESS are you using?
 
Access 2002 SP3

I have a Sub called SetControls that I call in Form_Current AfterUpdate of
several controls. It enables/disables certain controls based on the value of
other controls. For instance, here is an excerpt of that Sub that disables
the BuyerContract field until the Buyer is entered:

If IsNull (Buyer) Then
BuyerContract.Enabled = False
Else
BuyerContract.Enabled = True
End If

The problem is getting this to fire when Buyer is undone. I cannot use
Buyer.OldValue because I may call this from many places in the module when
Buyer has no OldValue. Since I first posted, I think I found a better
solution.

I tried calling my Sub from Form_Undo. However, the value of Buyer is still
its OldValue at the time Form_Undo fires. Furthermore, I need to ensure that
the focus moves away from BuyerContract before it is disabled, which would
generate an error.

I finally resorted to turning on KeyPreview for the form and running this:

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 27 Then 'user presses ESC
Status.SetFocus 'moves the focus off a control that may be disabled in
next step
SetControls
End If
End Sub

Better ideas?

Thanks.
 
You could try using the Exit event of the controls to run the code. At that
point, your control's value will be whatever is to remain in the control
when the person leaves the control.
 
Here is another example that may clarify. I have a combo box call Status
whose RowSource is a Value list that includes "Open" & "Closed".

In Status_AfterUpdate, I call the SetControls Sub. Part of that says:
If Status = "Closed" then
[disable all other controls].

Thus, when the user picks "Closed" from the combo box, Status_AfterUpdate
fires, and the SetControls Sub disables all other controls on the form; when
the user picks "Open", SetControls enables all other controls. If the user
picks "Closed" (thus causing SetControls to disable all other controls) and
then presses ESC, Status reverts to "Open" but all controls remain disabled.

Status_Exit would not fire, because the user has not moved to a different
control. Of course, this problem does not apply if the user types "Closed"
instead of picking it, because it does not update until the user presses TAB
or ENTER, and there is no need to run SetControls until the control actually
updates.

Since I run SetControls on Form_Current to enable/disable the same set of
controls, I cannot use Status.OldValue; OldValue will be null on Form_Current.
 
Here is perhaps a better example. I have a combo box called Status having
RowSource ValueList including "Open";"Closed".

Status_AfterUpdate calls SetControls. The germane portion of SetControls is:

If Status = "Closed" Then
[Several lines here to disable all other controls)
Else
[Several lines here to enable all other controls)
End If

When user picks "Closed" from Status, Status_AfterUpdate fires, and all
other controls are disabled by SetControls. The user now, without moving to
another control, presses ESC. Status is now "Open", but all other controls
remain disabled. If user types "Closed" rather than picking it from dropdown
list, then Status_AfterUpdate does not fire until Status_Exit, so the problem
does not exist in the same way.

I thought I could resolve this with Form_Undo, but here again, the OldValues
are still in place. The root question is how to call SetControls after a
particular control or the entire form reverts to OldValue.

For a workaround, I enabled Form.KeyPreview and call SetControls if KeyPress
is ESC. This works except when user presses ESC while in one of the controls
that gets disabled by SetControls, so I move the focus to a known enabled
control before running SetControls. This, in turn, causes a error (Can't move
focus...) when I drop down any combo box, begin typing the entry, and then
press ESC.

Thanks.
 
I've found it difficult to follow the example, but I'll offer two general
observations in the hope that they may be of some use.

First, if you need to keep track of changes to a control value across the
various events that are fired when a control value changes, and OldValue
doesn't meet your requirements, consider storing the values yourself in
module-level variables.

Second, I have, unfortunately, found the form and control undo event
procedures to be useless for all the purposes for which I might want to use
them, because they are single events that fire (if I remember correctly)
after the undo operation is complete. What we need is Before Undo and After
Undo events, in the same way that we have Before Update and After Update
events. In the absence of these, I often find myself forced to resort to the
Timer event to ensure that controls are enabled or disabled when they should
be.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible for
me to use a real e-mail address in public newsgroups. E-mail replies to
this post will be deleted without being read. Any e-mail claiming to be
from brenreyn at indigo dot ie that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me e-mail, you'll find
a useable e-mail address at the URL above.


Brian said:
Here is perhaps a better example. I have a combo box called Status having
RowSource ValueList including "Open";"Closed".

Status_AfterUpdate calls SetControls. The germane portion of SetControls
is:

If Status = "Closed" Then
[Several lines here to disable all other controls)
Else
[Several lines here to enable all other controls)
End If

When user picks "Closed" from Status, Status_AfterUpdate fires, and all
other controls are disabled by SetControls. The user now, without moving
to
another control, presses ESC. Status is now "Open", but all other controls
remain disabled. If user types "Closed" rather than picking it from
dropdown
list, then Status_AfterUpdate does not fire until Status_Exit, so the
problem
does not exist in the same way.

I thought I could resolve this with Form_Undo, but here again, the
OldValues
are still in place. The root question is how to call SetControls after a
particular control or the entire form reverts to OldValue.

For a workaround, I enabled Form.KeyPreview and call SetControls if
KeyPress
is ESC. This works except when user presses ESC while in one of the
controls
that gets disabled by SetControls, so I move the focus to a known enabled
control before running SetControls. This, in turn, causes a error (Can't
move
focus...) when I drop down any combo box, begin typing the entry, and then
press ESC.

Thanks.

Ken Snell said:
You could try using the Exit event of the controls to run the code. At
that
point, your control's value will be whatever is to remain in the control
when the person leaves the control.
 
Yes, AfterUndo is on my wish list here. Let me simplify this in case you can
think of a better methodology for my underlying task:

The value of [ComboBox] A is prerequisite for [Text Boxes] B & C, so I want
to disable B & C while A is null. The problem occurs when the user picks a
value in A (enables B & C) and later presses ESC (nullifies A but leaves B &
C incorrectly enabled).

Timer could get me closer to state-based processing instead of event-driven
processing; however, multiply the above by six or eight A/B, A/BC, or even
A/BCD combinations (i.e. if A is null, disable B, C, & D), and run it twice
per second to ensure that the screen refreshes for the user. Is that likely
to affect performance significantly?

This is all in an effort to avoid a lot of cross-checking and user
notification in Form_BeforeUpdate ("If IsNull(A) And Not IsNull(B) Then
[Cancel and notify user that there is a conflict]")

Thanks for your help.

Brendan Reynolds said:
I've found it difficult to follow the example, but I'll offer two general
observations in the hope that they may be of some use.

First, if you need to keep track of changes to a control value across the
various events that are fired when a control value changes, and OldValue
doesn't meet your requirements, consider storing the values yourself in
module-level variables.

Second, I have, unfortunately, found the form and control undo event
procedures to be useless for all the purposes for which I might want to use
them, because they are single events that fire (if I remember correctly)
after the undo operation is complete. What we need is Before Undo and After
Undo events, in the same way that we have Before Update and After Update
events. In the absence of these, I often find myself forced to resort to the
Timer event to ensure that controls are enabled or disabled when they should
be.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible for
me to use a real e-mail address in public newsgroups. E-mail replies to
this post will be deleted without being read. Any e-mail claiming to be
from brenreyn at indigo dot ie that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me e-mail, you'll find
a useable e-mail address at the URL above.


Brian said:
Here is perhaps a better example. I have a combo box called Status having
RowSource ValueList including "Open";"Closed".

Status_AfterUpdate calls SetControls. The germane portion of SetControls
is:

If Status = "Closed" Then
[Several lines here to disable all other controls)
Else
[Several lines here to enable all other controls)
End If

When user picks "Closed" from Status, Status_AfterUpdate fires, and all
other controls are disabled by SetControls. The user now, without moving
to
another control, presses ESC. Status is now "Open", but all other controls
remain disabled. If user types "Closed" rather than picking it from
dropdown
list, then Status_AfterUpdate does not fire until Status_Exit, so the
problem
does not exist in the same way.

I thought I could resolve this with Form_Undo, but here again, the
OldValues
are still in place. The root question is how to call SetControls after a
particular control or the entire form reverts to OldValue.

For a workaround, I enabled Form.KeyPreview and call SetControls if
KeyPress
is ESC. This works except when user presses ESC while in one of the
controls
that gets disabled by SetControls, so I move the focus to a known enabled
control before running SetControls. This, in turn, causes a error (Can't
move
focus...) when I drop down any combo box, begin typing the entry, and then
press ESC.

Thanks.

Ken Snell said:
You could try using the Exit event of the controls to run the code. At
that
point, your control's value will be whatever is to remain in the control
when the person leaves the control.

--

Ken Snell
<MS ACCESS MVP>

Access 2002 SP3

I have a Sub called SetControls that I call in Form_Current AfterUpdate
of
several controls. It enables/disables certain controls based on the
value
of
other controls. For instance, here is an excerpt of that Sub that
disables
the BuyerContract field until the Buyer is entered:

If IsNull (Buyer) Then
BuyerContract.Enabled = False
Else
BuyerContract.Enabled = True
End If

The problem is getting this to fire when Buyer is undone. I cannot use
Buyer.OldValue because I may call this from many places in the module
when
Buyer has no OldValue. Since I first posted, I think I found a better
solution.

I tried calling my Sub from Form_Undo. However, the value of Buyer is
still
its OldValue at the time Form_Undo fires. Furthermore, I need to ensure
that
the focus moves away from BuyerContract before it is disabled, which
would
generate an error.

I finally resorted to turning on KeyPreview for the form and running
this:

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 27 Then 'user presses ESC
Status.SetFocus 'moves the focus off a control that may be disabled
in
next step
SetControls
End If
End Sub

Better ideas?

Thanks.

:

How does that Sub know what the value of the control is, regardless of
whether it's the original or current value? You'll need to tell us
more
info... I'm not convinced yet that you cannot use the OldValue value,
especially if you pass the control object as an argument to the
subroutine
itself.

Which version of ACCESS are you using?

--

Ken Snell
<MS ACCESS MVP>


How can I get an event to fire after the undo of a control?

I need to use the original value of the control in running another
Sub
after
undoing the control, but the value does not revert until after the
Undo
event
is complete. I cannot simply use the ControlName.OldValue because I
run
the
same Sub (using the reference to this and other control names) in
several
other places in this module.
 
While I try to avoid using the Timer event when there's a good alternative,
my experience has been that on those occasions when I have used it, I have
not actually noticed any perceivable degradation of performance. I usually
use an interval of 250 milliseconds, one quarter of a second. Apparently,
this is the smallest time interval that most people consciously perceive,
anything less than this is effectively instantaneous.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible for
me to use a real a-mail address in public newsgroups. A-mail replies to
this post will be deleted without being read. Any a-mail claiming to be
from brenreyn at indigo dot i.e. that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me a-mail, you'll find
a useable a-mail address at the URL above.


Brian said:
Yes, AfterUndo is on my wish list here. Let me simplify this in case you
can
think of a better methodology for my underlying task:

The value of [ComboBox] A is prerequisite for [Text Boxes] B & C, so I
want
to disable B & C while A is null. The problem occurs when the user picks
a
value in A (enables B & C) and later presses ESC (nullifies A but leaves B
&
C incorrectly enabled).

Timer could get me closer to state-based processing instead of
event-driven
processing; however, multiply the above by six or eight A/B, A/BC, or even
A/BCD combinations (i.e. if A is null, disable B, C, & D), and run it
twice
per second to ensure that the screen refreshes for the user. Is that
likely
to affect performance significantly?

This is all in an effort to avoid a lot of cross-checking and user
notification in Form_BeforeUpdate ("If IsNull(A) And Not IsNull(B) Then
[Cancel and notify user that there is a conflict]")

Thanks for your help.

Brendan Reynolds said:
I've found it difficult to follow the example, but I'll offer two general
observations in the hope that they may be of some use.

First, if you need to keep track of changes to a control value across the
various events that are fired when a control value changes, and OldValue
doesn't meet your requirements, consider storing the values yourself in
module-level variables.

Second, I have, unfortunately, found the form and control undo event
procedures to be useless for all the purposes for which I might want to
use
them, because they are single events that fire (if I remember correctly)
after the undo operation is complete. What we need is Before Undo and
After
Undo events, in the same way that we have Before Update and After Update
events. In the absence of these, I often find myself forced to resort to
the
Timer event to ensure that controls are enabled or disabled when they
should
be.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible
for
me to use a real e-mail address in public newsgroups. E-mail replies to
this post will be deleted without being read. Any e-mail claiming to be
from brenreyn at indigo dot ie that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me e-mail, you'll find
a useable e-mail address at the URL above.


Brian said:
Here is perhaps a better example. I have a combo box called Status
having
RowSource ValueList including "Open";"Closed".

Status_AfterUpdate calls SetControls. The germane portion of
SetControls
is:

If Status = "Closed" Then
[Several lines here to disable all other controls)
Else
[Several lines here to enable all other controls)
End If

When user picks "Closed" from Status, Status_AfterUpdate fires, and all
other controls are disabled by SetControls. The user now, without
moving
to
another control, presses ESC. Status is now "Open", but all other
controls
remain disabled. If user types "Closed" rather than picking it from
dropdown
list, then Status_AfterUpdate does not fire until Status_Exit, so the
problem
does not exist in the same way.

I thought I could resolve this with Form_Undo, but here again, the
OldValues
are still in place. The root question is how to call SetControls after
a
particular control or the entire form reverts to OldValue.

For a workaround, I enabled Form.KeyPreview and call SetControls if
KeyPress
is ESC. This works except when user presses ESC while in one of the
controls
that gets disabled by SetControls, so I move the focus to a known
enabled
control before running SetControls. This, in turn, causes a error
(Can't
move
focus...) when I drop down any combo box, begin typing the entry, and
then
press ESC.

Thanks.

:

You could try using the Exit event of the controls to run the code. At
that
point, your control's value will be whatever is to remain in the
control
when the person leaves the control.

--

Ken Snell
<MS ACCESS MVP>

Access 2002 SP3

I have a Sub called SetControls that I call in Form_Current
AfterUpdate
of
several controls. It enables/disables certain controls based on the
value
of
other controls. For instance, here is an excerpt of that Sub that
disables
the BuyerContract field until the Buyer is entered:

If IsNull (Buyer) Then
BuyerContract.Enabled = False
Else
BuyerContract.Enabled = True
End If

The problem is getting this to fire when Buyer is undone. I cannot
use
Buyer.OldValue because I may call this from many places in the
module
when
Buyer has no OldValue. Since I first posted, I think I found a
better
solution.

I tried calling my Sub from Form_Undo. However, the value of Buyer
is
still
its OldValue at the time Form_Undo fires. Furthermore, I need to
ensure
that
the focus moves away from BuyerContract before it is disabled, which
would
generate an error.

I finally resorted to turning on KeyPreview for the form and running
this:

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 27 Then 'user presses ESC
Status.SetFocus 'moves the focus off a control that may be
disabled
in
next step
SetControls
End If
End Sub

Better ideas?

Thanks.

:

How does that Sub know what the value of the control is, regardless
of
whether it's the original or current value? You'll need to tell us
more
info... I'm not convinced yet that you cannot use the OldValue
value,
especially if you pass the control object as an argument to the
subroutine
itself.

Which version of ACCESS are you using?

--

Ken Snell
<MS ACCESS MVP>


How can I get an event to fire after the undo of a control?

I need to use the original value of the control in running
another
Sub
after
undoing the control, but the value does not revert until after
the
Undo
event
is complete. I cannot simply use the ControlName.OldValue because
I
run
the
same Sub (using the reference to this and other control names) in
several
other places in this module.
 
I tried Timer, and it works well, but I had to change this (times about 40):

ControlA.Enabled = True

to this:

If ControlA.Enabled Then
If Screen.ActiveControl.Name = "ControlA" Then OtherControl.SetFocus
ControlA.Enabled = False
End If

First "If" prevents re-enabling control if already enabled; if this happens
when the user has that combo box dropped down, the dropdown is cancelled.
Second "If" prevents error that occurs when disabling the control that has
the focus.

It works without a hitch now, but oh, how I wish for that Form_AfterUndo...

Thanks for the help.

Brendan Reynolds said:
While I try to avoid using the Timer event when there's a good alternative,
my experience has been that on those occasions when I have used it, I have
not actually noticed any perceivable degradation of performance. I usually
use an interval of 250 milliseconds, one quarter of a second. Apparently,
this is the smallest time interval that most people consciously perceive,
anything less than this is effectively instantaneous.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible for
me to use a real a-mail address in public newsgroups. A-mail replies to
this post will be deleted without being read. Any a-mail claiming to be
from brenreyn at indigo dot i.e. that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me a-mail, you'll find
a useable a-mail address at the URL above.


Brian said:
Yes, AfterUndo is on my wish list here. Let me simplify this in case you
can
think of a better methodology for my underlying task:

The value of [ComboBox] A is prerequisite for [Text Boxes] B & C, so I
want
to disable B & C while A is null. The problem occurs when the user picks
a
value in A (enables B & C) and later presses ESC (nullifies A but leaves B
&
C incorrectly enabled).

Timer could get me closer to state-based processing instead of
event-driven
processing; however, multiply the above by six or eight A/B, A/BC, or even
A/BCD combinations (i.e. if A is null, disable B, C, & D), and run it
twice
per second to ensure that the screen refreshes for the user. Is that
likely
to affect performance significantly?

This is all in an effort to avoid a lot of cross-checking and user
notification in Form_BeforeUpdate ("If IsNull(A) And Not IsNull(B) Then
[Cancel and notify user that there is a conflict]")

Thanks for your help.

Brendan Reynolds said:
I've found it difficult to follow the example, but I'll offer two general
observations in the hope that they may be of some use.

First, if you need to keep track of changes to a control value across the
various events that are fired when a control value changes, and OldValue
doesn't meet your requirements, consider storing the values yourself in
module-level variables.

Second, I have, unfortunately, found the form and control undo event
procedures to be useless for all the purposes for which I might want to
use
them, because they are single events that fire (if I remember correctly)
after the undo operation is complete. What we need is Before Undo and
After
Undo events, in the same way that we have Before Update and After Update
events. In the absence of these, I often find myself forced to resort to
the
Timer event to ensure that controls are enabled or disabled when they
should
be.

--
Brendan Reynolds (MVP)
http://brenreyn.blogspot.com

The spammers and script-kiddies have succeeded in making it impossible
for
me to use a real e-mail address in public newsgroups. E-mail replies to
this post will be deleted without being read. Any e-mail claiming to be
from brenreyn at indigo dot ie that is not digitally signed by me with a
GlobalSign digital certificate is a forgery and should be deleted without
being read. Follow-up questions should in general be posted to the
newsgroup, but if you have a good reason to send me e-mail, you'll find
a useable e-mail address at the URL above.


Here is perhaps a better example. I have a combo box called Status
having
RowSource ValueList including "Open";"Closed".

Status_AfterUpdate calls SetControls. The germane portion of
SetControls
is:

If Status = "Closed" Then
[Several lines here to disable all other controls)
Else
[Several lines here to enable all other controls)
End If

When user picks "Closed" from Status, Status_AfterUpdate fires, and all
other controls are disabled by SetControls. The user now, without
moving
to
another control, presses ESC. Status is now "Open", but all other
controls
remain disabled. If user types "Closed" rather than picking it from
dropdown
list, then Status_AfterUpdate does not fire until Status_Exit, so the
problem
does not exist in the same way.

I thought I could resolve this with Form_Undo, but here again, the
OldValues
are still in place. The root question is how to call SetControls after
a
particular control or the entire form reverts to OldValue.

For a workaround, I enabled Form.KeyPreview and call SetControls if
KeyPress
is ESC. This works except when user presses ESC while in one of the
controls
that gets disabled by SetControls, so I move the focus to a known
enabled
control before running SetControls. This, in turn, causes a error
(Can't
move
focus...) when I drop down any combo box, begin typing the entry, and
then
press ESC.

Thanks.

:

You could try using the Exit event of the controls to run the code. At
that
point, your control's value will be whatever is to remain in the
control
when the person leaves the control.

--

Ken Snell
<MS ACCESS MVP>

Access 2002 SP3

I have a Sub called SetControls that I call in Form_Current
AfterUpdate
of
several controls. It enables/disables certain controls based on the
value
of
other controls. For instance, here is an excerpt of that Sub that
disables
the BuyerContract field until the Buyer is entered:

If IsNull (Buyer) Then
BuyerContract.Enabled = False
Else
BuyerContract.Enabled = True
End If

The problem is getting this to fire when Buyer is undone. I cannot
use
Buyer.OldValue because I may call this from many places in the
module
when
Buyer has no OldValue. Since I first posted, I think I found a
better
solution.

I tried calling my Sub from Form_Undo. However, the value of Buyer
is
still
its OldValue at the time Form_Undo fires. Furthermore, I need to
ensure
that
the focus moves away from BuyerContract before it is disabled, which
would
generate an error.

I finally resorted to turning on KeyPreview for the form and running
this:

Private Sub Form_KeyPress(KeyAscii As Integer)
If KeyAscii = 27 Then 'user presses ESC
Status.SetFocus 'moves the focus off a control that may be
disabled
in
next step
SetControls
End If
End Sub

Better ideas?

Thanks.

:

How does that Sub know what the value of the control is, regardless
of
whether it's the original or current value? You'll need to tell us
more
info... I'm not convinced yet that you cannot use the OldValue
value,
especially if you pass the control object as an argument to the
subroutine
itself.

Which version of ACCESS are you using?

--

Ken Snell
<MS ACCESS MVP>


How can I get an event to fire after the undo of a control?

I need to use the original value of the control in running
another
Sub
after
undoing the control, but the value does not revert until after
the
Undo
event
is complete. I cannot simply use the ControlName.OldValue because
I
run
the
same Sub (using the reference to this and other control names) in
several
other places in this module.
 
Back
Top