访问 2007 窗体:撤消后的事件
Access 2007 form: event AFTER undo
我在 Access 2007 中有一个表单,它有一个 "update" 例程,可以根据其他字段(文本框、复选框、组合框)中的值启用或禁用某些文本框。该例程的常规操作效果很好。
现在我发现按ESC键会调用撤销功能,恢复所有字段的原始值。但是此撤消不会调用这些字段上的事件,因此表单处于错误状态,其中文本框是 disabled/enabled 尽管它们不应该。
我还发现有一个撤消事件,但这对我没用,因为它是在撤消之前调用的。撤消后我需要一个事件。当按下 ESC 时,我可以在这里做什么来更新字段?
好吧,就像很多次一样,我在发布问题后有了解决方案的想法。
此处的解决方案是在窗体上启用 KeyPreview 并使用 KeyUp 事件。撤消是在 KeyDown 上调用的,因此当 KeyUp 被触发时,表单已经再次具有恢复的值并且更新例程有效。
我更喜欢这个解决方案,因为它不仅适用于 "ESC"-Key:
private Sub form_Undo(cancel as integer)
afterUndo = true
TimerInterval = 1
end Sub
private Sub Form_Timer()
if afterUndo then
'do something after the Undo-Event
end if
TimerInterval = 0
end Sub
这个问题的另一种解决方法是使用每个控件的OldValue
属性。通过实验,我发现控件的三个不同的值属性在不同的情况下发挥作用:
Control.Value
或简单地 Control
- 大部分时间控件的当前值
- 控件获得焦点时,为控件获得焦点前的值
- 在
Form.Undo
事件期间,它是撤消之前控件的值
- 在
Control.AfterUpdate
和 Control.Undo
事件期间相关
Control.Text
- 控件获得焦点时的值
- 在用户键入事件期间相关,例如
Control.Change
、Control.KeyUp
、Control.KeyDown
Control.OldValue
- 第一次打开当前记录时控件的值
- 也是 form-level 撤消会将控件重置为
的值
- 在
Form.Undo
事件期间相关
这个问题的 timer-based 答案是我的 go-to 解决方案,但是如果您已经在处理用户类型的事件(例如,用于实时验证),那么这样的代码可以是明智的:
Private Sub LastName_Change()
ValidateLastName SourceProperty:="Text"
End Sub
Private Sub LastName_Undo(Cancel As Integer)
ValidateLastName SourceProperty:="Value"
End Sub
Private Sub Form_Undo(Cancel As Integer)
ValidateLastName SourceProperty:="OldValue"
End Sub
Private Sub ValidateLastName(SourceProperty As Variant)
Dim LastName As String
Select Case SourceProperty
Case "LastName"
LastName = Nz(Me.LastName.Text, "")
Case "Value"
LastName = Nz(Me.LastName.Value, "")
Case "OldValue"
LastName = Nz(Me.LastName.OldValue, "")
Case Else
Debug.Print "Invalid case in ValidateLastName"
Exit Sub
End Select
' <Do something to validate LastName>
End Sub
请注意,此方法无法让您访问 combo/list 个框的 Control.Column(x)
的 post-Form-Undo 值。您可以通过在 Control.OldValue
上使用 DLOOKUP
来获得它,但您最好只使用 timer-based 解决方案。
我在 Access 2007 中有一个表单,它有一个 "update" 例程,可以根据其他字段(文本框、复选框、组合框)中的值启用或禁用某些文本框。该例程的常规操作效果很好。
现在我发现按ESC键会调用撤销功能,恢复所有字段的原始值。但是此撤消不会调用这些字段上的事件,因此表单处于错误状态,其中文本框是 disabled/enabled 尽管它们不应该。
我还发现有一个撤消事件,但这对我没用,因为它是在撤消之前调用的。撤消后我需要一个事件。当按下 ESC 时,我可以在这里做什么来更新字段?
好吧,就像很多次一样,我在发布问题后有了解决方案的想法。
此处的解决方案是在窗体上启用 KeyPreview 并使用 KeyUp 事件。撤消是在 KeyDown 上调用的,因此当 KeyUp 被触发时,表单已经再次具有恢复的值并且更新例程有效。
我更喜欢这个解决方案,因为它不仅适用于 "ESC"-Key:
private Sub form_Undo(cancel as integer)
afterUndo = true
TimerInterval = 1
end Sub
private Sub Form_Timer()
if afterUndo then
'do something after the Undo-Event
end if
TimerInterval = 0
end Sub
这个问题的另一种解决方法是使用每个控件的OldValue
属性。通过实验,我发现控件的三个不同的值属性在不同的情况下发挥作用:
Control.Value
或简单地Control
- 大部分时间控件的当前值
- 控件获得焦点时,为控件获得焦点前的值
- 在
Form.Undo
事件期间,它是撤消之前控件的值 - 在
Control.AfterUpdate
和Control.Undo
事件期间相关
Control.Text
- 控件获得焦点时的值
- 在用户键入事件期间相关,例如
Control.Change
、Control.KeyUp
、Control.KeyDown
Control.OldValue
- 第一次打开当前记录时控件的值
- 也是 form-level 撤消会将控件重置为 的值
- 在
Form.Undo
事件期间相关
这个问题的 timer-based 答案是我的 go-to 解决方案,但是如果您已经在处理用户类型的事件(例如,用于实时验证),那么这样的代码可以是明智的:
Private Sub LastName_Change()
ValidateLastName SourceProperty:="Text"
End Sub
Private Sub LastName_Undo(Cancel As Integer)
ValidateLastName SourceProperty:="Value"
End Sub
Private Sub Form_Undo(Cancel As Integer)
ValidateLastName SourceProperty:="OldValue"
End Sub
Private Sub ValidateLastName(SourceProperty As Variant)
Dim LastName As String
Select Case SourceProperty
Case "LastName"
LastName = Nz(Me.LastName.Text, "")
Case "Value"
LastName = Nz(Me.LastName.Value, "")
Case "OldValue"
LastName = Nz(Me.LastName.OldValue, "")
Case Else
Debug.Print "Invalid case in ValidateLastName"
Exit Sub
End Select
' <Do something to validate LastName>
End Sub
请注意,此方法无法让您访问 combo/list 个框的 Control.Column(x)
的 post-Form-Undo 值。您可以通过在 Control.OldValue
上使用 DLOOKUP
来获得它,但您最好只使用 timer-based 解决方案。