用户表单取消按钮_间歇性_无响应?

发布于 2024-08-19 12:19:11 字数 2145 浏览 5 评论 0原文

所附的 VBA 程序适用于进度条用户窗体。一切都按预期工作,除了取消按钮间歇性无响应。

我之所以说“间歇性”,是因为 95% 的情况下,我必须在程序停止之前多次单击取消按钮。我可以看到按钮单击事件正在动画化,但过程没有被中断。看起来好像有什么东西在发生按钮按下事件之前从取消按钮上窃取了焦点。

单击一下即可按预期响应退出和窗口关闭按钮。

我需要做什么才能使取消按钮正确响应?谢谢!

更新:我注意到,当我单击并按住取消按钮时,按钮不会保持“按下”状态,而是被踢回原处。因此,显然有些东西正在将按钮状态重置为向上,速度足够快,以至于程序无法捕获向下状态来触发单击事件。

以下是用户表单模块(名为 UserForm1)中的代码:

Private mbooUserCancel As Boolean

Public Property Get UserCancel() As Boolean
    UserCancel = mbooUserCancel
End Property

Private Property Let UserCancel(ByVal booUserCancel As Boolean)
    mbooUserCancel = booUserCancel
End Property

Public Sub UpdateProgress(CountTotal As Long, CountProgress As Long)
    On Error GoTo Error_Handler
    ProgressBar1.Value = CountProgress / CountTotal * 100
    DoEvents
Error_Handler:
    If Err.Number = 18 Then CommandButton1_Click
End Sub

Private Sub CommandButton1_Click()
    Hide
    UserCancel = True
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    CommandButton1_Click
End Sub

Private Sub UserForm_Activate()
    With Application
        .Interactive = False
        .EnableCancelKey = xlErrorHandler
    End With
End Sub

Private Sub UserForm_Terminate()
    Application.Interactive = True
End Sub

以下是调用 UserForm1 的模块(名为 Module1)的代码:

Sub TestProgress()

    On Error GoTo Error_Handler

    Dim objUserForm As New UserForm1
    Dim lngCounter As Long
    Dim lngSubCounter As Long

    With objUserForm
        .Show vbModeless
        DoEvents
        For lngCounter = 1 To 5
            If .UserCancel Then GoTo Exit_Sub
            For lngSubCounter = 1 To 100000000
            Next lngSubCounter
            .UpdateProgress 5, lngCounter
        Next lngCounter
        Application.Wait Now + TimeValue("0:00:02")
        .Hide
    End With

Exit_Sub:

    If objUserForm.UserCancel Then
        MsgBox "User Cancelled from UserForm1"
    End If
    Exit Sub

Error_Handler:

    If Err.Number = 18 Then
        Unload objUserForm
        MsgBox "User Cancelled from Module1"
    End If

End Sub

The attached VBA procedures are for a progress bar userform. Everything works as expected, except that the cancel button is intermittently unresponsive.

I say intermittently because, 95% of the time I have to click the cancel button numerous times before the procedure stops. I can see the button click event being animated, but the procedure isn't being interrupted. It looks as though something is stealing focus from the cancel button before the button down event can occur.

The escape and window close buttons respond as expected with one click.

What do I need to do to make the cancel button respond correctly? Thanks!

Update: I noticed that when I click and hold down on the cancel button, instead of the button staying "down" it gets kicked back up. So apparently something is resetting the button state to up, fast enough that the procedure is not catching the down state to fire the click event.

Here is the code in the userform module (named UserForm1):

Private mbooUserCancel As Boolean

Public Property Get UserCancel() As Boolean
    UserCancel = mbooUserCancel
End Property

Private Property Let UserCancel(ByVal booUserCancel As Boolean)
    mbooUserCancel = booUserCancel
End Property

Public Sub UpdateProgress(CountTotal As Long, CountProgress As Long)
    On Error GoTo Error_Handler
    ProgressBar1.Value = CountProgress / CountTotal * 100
    DoEvents
Error_Handler:
    If Err.Number = 18 Then CommandButton1_Click
End Sub

Private Sub CommandButton1_Click()
    Hide
    UserCancel = True
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Cancel = True
    CommandButton1_Click
End Sub

Private Sub UserForm_Activate()
    With Application
        .Interactive = False
        .EnableCancelKey = xlErrorHandler
    End With
End Sub

Private Sub UserForm_Terminate()
    Application.Interactive = True
End Sub

Here is the code for the module (named Module1) that calls the UserForm1:

Sub TestProgress()

    On Error GoTo Error_Handler

    Dim objUserForm As New UserForm1
    Dim lngCounter As Long
    Dim lngSubCounter As Long

    With objUserForm
        .Show vbModeless
        DoEvents
        For lngCounter = 1 To 5
            If .UserCancel Then GoTo Exit_Sub
            For lngSubCounter = 1 To 100000000
            Next lngSubCounter
            .UpdateProgress 5, lngCounter
        Next lngCounter
        Application.Wait Now + TimeValue("0:00:02")
        .Hide
    End With

Exit_Sub:

    If objUserForm.UserCancel Then
        MsgBox "User Cancelled from UserForm1"
    End If
    Exit Sub

Error_Handler:

    If Err.Number = 18 Then
        Unload objUserForm
        MsgBox "User Cancelled from Module1"
    End If

End Sub

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春有你 2024-08-26 12:19:11

每次第一次点击都对我有用。尝试卸载可能在容器应用程序内运行的任何加载项或任何其他代码,看看是否有帮助。

Works for me on the first click every time. Try unloading any add-ins or any other code that could be running inside the container app and see if that helps.

七禾 2024-08-26 12:19:11

如果人们仍然需要答案,那么我研究并解决了这个问题。破解了它!

对于单击取消按钮,代码应该是;

Private Sub CommandButton1_Click()

Unload Me

'this bit ends all macros

End

End Sub

If people are still in need of the answer, well I researched & cracked it!

For the click on cancel button, code should be;

Private Sub CommandButton1_Click()

Unload Me

'this bit ends all macros

End

End Sub
╰つ倒转 2024-08-26 12:19:11

答案是使用进度条的模态用户窗体,以便按钮单击事件可以触发,而不会被调用过程中的处理所掩盖。

The answer is to use modal userforms for progress bars so that the button click event can fire without getting obscured by processing in the calling procedure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文