访问 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.AfterUpdateControl.Undo 事件期间相关
  • Control.Text

    • 控件获得焦点时的值
    • 在用户键入事件期间相关,例如 Control.ChangeControl.KeyUpControl.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 解决方案。