Userform的Enter事件不会触发

时间:2017-05-01 14:48:37

标签: ms-word word-vba

我有一个包含许多帧的用户表单,每个帧都有许多文本框。如果Tbx为空,则某些Tbx具有导致自动填充的事件过程。他们都工作。但是,如果我删除自动填充的内容,请转到另一个控件,然后再次单击第一个控件,事件不会触发。我点击的内容和位置并不重要,直到我点击同一帧中的另一个控件然后我正在测试的那个控件时才会发生任何事情。只有在那个序列中,事件才会再次发射。

单击,删除,单击同一帧中的另一个控件,然后在第一个控件中再次单击,每次都会自动填充。只是当我删除时,单击另一帧中的控件然后返回预期的事件不会发生。

我知道帧和控件之间事件的排序很复杂。我相信当我单击另一个帧中的控件时,测试控件的Exit事件不会发生,实际上只有在我单击同一帧中的另一个控件时才会发生Exit事件,并且Enter事件简单地说,因为Exit事件没有在它之前发生,所以不管我在此期间实际点击了哪些其他帧。

这个逻辑虽然显然看似合理,但是,当考虑到我在另一个帧中有另一个自动填充Tbx并且来自我正在测试的Tbx时,其他Enter事件确实会触发,这很奇怪。因此,可能确实发生了Enter事件的第二帧,启用了对Enter事件的控制以自动填充它。如果没有针对正在进行测试的Tbx的Exit事件,那么所有Enter事件如何发生?好吧,关于Word的一切都不合逻辑。

但也许有人有这方面的经验,可以告诉我如何强制第一个控件或其框架的Exit事件,或者其他事件可能更适合这个特定目的。

谢谢。

2 个答案:

答案 0 :(得分:1)

创建一个包含2个框架的UserForm,每个框架包含2个TextBox控件,并使用以下代码进行测试/调试。

Private Sub Frame1_Enter()
    MsgMe "frm1 enter"
End Sub

Private Sub Frame1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    MsgMe "frm1 exit"
End Sub

    Private Sub TextBox1_Enter()
        MsgMe "tb1 enter"
    End Sub

    Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        MsgMe "tb1 exit"
    End Sub


    Private Sub TextBox2_Enter()
        MsgMe "tb2 enter"
    End Sub

    Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        MsgMe "tb2 exit"
    End Sub

Private Sub Frame2_Enter()
    MsgMe "frm2 enter"
End Sub
Private Sub Frame2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    MsgMe "frm2 exit"
End Sub

    Private Sub TextBox3_Enter()
        MsgMe "tb3 enter"
    End Sub

    Private Sub TextBox3_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        MsgMe "tb3 exit"
    End Sub
    Private Sub TextBox4_Enter()
        MsgMe "tb4 enter"
    End Sub

    Private Sub TextBox4_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        MsgMe "tb4 exit"
    End Sub

Sub MsgMe(str$)
    Debug.Print str
End Sub

您的怀疑似乎是正确的。

  

我相信当我单击另一帧中的控件时,测试控件的Exit事件不会发生,事实上,当我在同一帧中单击另一个控件时,Exit事件才会发生,并且简单地说,Enter事件不会发生,因为Exit事件没有在它之前发生,而不管我在此期间实际点击了哪些其他帧

我相信这就是原因:

  1. 显示UserForm,并观察此事件会触发Frame1_Enter事件 TextBox1_Enter事件。
  2. 点击TextBox3并观察此触发器Frame1_Exit,然后Frame2_Enter,最后是TextBox3_Enter事件,但 TextBox1_Exit事件。
  3. 点击回到Frame1,TextBox1中的任何控件,您将看到Frame1_Enter事件已经引发。 TextBox1_Exit事件尚未发生,因为您还没有退出此控件 - 当您在第2步中离开框架时,此控件仍然具有焦点,现在您将返回到它。
  4. 现在,做一些不同的事情:

    1. 显示UserForm,并观察此事件会触发Frame1_Enter事件 TextBox1_Enter事件。
    2. 点击TextBox3并观察此触发器Frame1_Exit,然后Frame2_Enter,最后是TextBox3_Enter事件,但 TextBox1_Exit事件。
    3. 现在,点击TextBox2(在第1帧中),您将观察以下事件序列:Form1_Enter1TextBox1_Exit,最后是TextBox2_Enter
    4. 如果您在文本框中添加了MouseDown事件处理程序,那么您将能够捕获控件尚未Exit编辑的情况,但您将返回焦点它/父框架。

      Private Sub TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
          MsgMe "tb1 mousedown"
      End Sub
      

答案 1 :(得分:1)

不情愿的TextBox的Exit事件可以用其他事件调用的类似过程替换。最合适的一个是框架的Enter事件,当框架中的任何控件被激活时可以触发,并且可以调用如下的过程。

    Dim PrevFrm As MSForms.Frame

Private Sub SetPrevControl()
    ' 02 May 2017

    If Not PrevFrm Is Nothing Then
        If Not PrevFrm.ActiveControl Is Nothing Then
            ' call the replacement Exit procedure here
            MsgMe "Trigger Exit for " & PrevFrm.ActiveControl.Name
        End If
    End If
    Set PrevFrm = ActiveControl
End Sub