Access 2007表单:事件撤消后

时间:2017-12-01 11:54:22

标签: forms access-vba ms-access-2007 keyevent

我在Access 2007中有一个表单,它有一个“更新”例程,可以根据其他字段(文本框,复选框,组合框)中的值启用或禁用某些文本框。该例程的常规操作运作良好。

现在我发现按ESC调用撤销功能,恢复所有字段中的原始值。但是这个撤消不会调用那些字段上的事件,因此表单处于错误的状态,文本框被禁用/启用,尽管它们不应该。

我还发现有一个撤消事件,但这对我来说没用,因为它在撤消之前被调用。撤消后我需要一个事件。在按下ESC时,我可以在此处更新字段?

3 个答案:

答案 0 :(得分:3)

我更喜欢这个解决方案,因为它不仅适用于“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 

答案 1 :(得分:1)

好吧,就像在我提出解决方案后我想出一个问题之前很多次一样。

此处的解决方案是在表单上启用KeyPreview并使用KeyUp事件。撤消在KeyDown上调用,因此当引发KeyUp时,表单已经再次具有恢复的值,并且更新例程可以正常工作。

答案 2 :(得分:0)

此问题的另一个解决方案是使用每个控件的OldValue属性。通过实验,我发现控件的三个不同的值属性在不同的情况下发挥作用:

  • Control.Value 或只是 Control

    • 大部分时间控件的当前值
    • 当控件具有焦点时,它是控制在获得焦点之前的值
    • Form.Undo事件期间,它是撤消之前控件的值
    • Control.AfterUpdateControl.Undo活动期间的相关内容
  • <强> Control.Text

    • 控件的焦点值
    • 在用户输入的事件期间相关,例如Control.ChangeControl.KeyUpControl.KeyDown
  • <强> Control.OldValue

    • 首次打开当前记录时控件的值
    • 此外,表单级撤消将控件重置为
    • 的值
    • Form.Undo活动期间的相关内容

这个问题的基于计时器的答案是我的首选解决方案,但如果你已经在用户输入时处理事件(例如,用于实时验证),那么这样的代码是明智的:

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

请注意,此方法无法让您访问组合/列表框Control.Column(x)的表单后撤消值。您可以在DLOOKUP上使用Control.OldValue来获取它,但您最好只使用基于计时器的解决方案。