VBA:在宏运行时禁用列表框

时间:2017-04-17 21:26:57

标签: excel vba excel-vba listbox ms-office

问题

我有一个宏(我称之为launch_macro),它是通过双击Userform ListBox(ListBox1_DblClick)启动的。

我的问题是,如果用户在宏仍在运行时再次双击,则在第一次执行完成后,宏将再次启动,而不管我是否禁用ListBox。宏正在运行。

代码和测试

Private sub ListBox1_DblClick(Byval Cancel as MSForms.ReturnBoolean)

   (....Logging...)

    If Not Cancel Then
        Me.ListBox1.Enabled = False
        (...DisplayStatusBar / ScreenUpdating / ListBox1.BackColor...)
        launch_macro
        (...DisplayStatusBar / ScreenUpdating / ListBox1.BackColor...)
        Me.ListBox1.Enabled = True

    End If

End sub

似乎Excel记录/排队 ListBox1_DblClick 事件(以备将来执行),而相关的 ListBox已禁用。为什么 ?我该如何防止这种情况?

我也尝试过没有成功:

  • 已锁定Me.ListBox1.Locked = True
  • Doevents :在DoEvents
  • 之后添加Me.ListBox1.Enabled = False
  • EnableEvents Application.EnableEvents = False
  • macroLaunched变量:使用变量检查宏是否已经启动(macroLaunched = True事件开始时为ListBox1_DblClick,最后为macroLaunched = False )。这是行不通的,因为第二次执行是在第一个事件结束后 启动的(因此变量被设置回False)。 (并且在Dbl_Click事件范围之外将变量设置回False是不可接受的,因为用户需要能够立即再次启动宏(但是在第一次执行仍在运行时却没有)。)
  • 添加延迟(仅用于测试目的):我在launch_macro之后添加了10s延迟(Application.Wait)。然后我在1s内双击两次。第二次执行仍然启动。我通过记录检查:第二个ListBox1.Dbl_Click事件是'记录'在第一次活动后通过Excel 12s。

注意:我使用的是Office Standard 2013

当前'解决方案'

这个技巧适用于(减少延迟)A.S.H答案:

Private sub ListBox1_DblClick(Byval Cancel as MSForms.ReturnBoolean)
   Static nextTime As Single

   If Timer < nextTime then
        Log_macro "Event canceled because Timer < nextTime : " & Timer
        Exit Sub
   End if

   (....Logging...)

    If Not Cancel Then
        (...DisplayStatusBar / ScreenUpdating / ListBox1.BackColor...)
        launch_macro
        (...DisplayStatusBar / ScreenUpdating / ListBox1.BackColor...)

    End If

    nextTime = Timer + 0.5
    Log_macro "nextTime = " & nextTime

End sub

它做的诀窍&#39;但我仍然不喜欢ListBox1仍然启用,Excel仍在排队事件,因此我需要估计用户可能有多少时间Dbl_Click(取决于宏需要多长时间)来估计延迟多少需要(目前0.5秒能够处理(并记录)至少10个已取消的事件)。此外,在宏运行时,Excel似乎并不喜欢(关于性能)排队事件。

2 个答案:

答案 0 :(得分:3)

我会发布我的建议,希望你试试,因为它可能被误解了。我们的想法是,一旦宏完成,我们在再次处理双击事件之前设置n秒的延迟(比如说2秒)。这样,在宏执行期间排队的dbl-clicks在这两秒钟内处理无效。

Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    Static NextTime As Variant ' Will set a barrier for launching again the macro 
    If Not IsEmpty(NextTime) Then If Now < NextTime Then Exit Sub

    ListBox1.Enabled = False
    ' Any event code
    launch_macro
    ' ...
    ListBox1.Enabled = True

    NextTime = Now + TimeSerial(0, 0, 2) ' dbl-click events will have no effects during next 2 seconds
End Sub

答案 1 :(得分:0)

您可以使用变量锁定代码的关键部分一段时间。 下面的示例锁定了Excel工作簿的Sheet2中Test()函数的关键部分。

Option Explicit
Private booIsRunning As Boolean
Private Sub Test()

    If Not booIsRunning Then
        booIsRunning = True
        Debug.Print "Hello."
        Application.OnTime Now + TimeValue("00:00:02"), "Sheet2.UnlockTest"
    End If
End Sub

Public Sub UnlockTest()
    booIsRunning = False
End Sub