VBA:macros正在运行时禁用列表框

问题

我有一个macros(我将它称为launch_macro ),这是通过双击用户窗体列表框( ListBox1_DblClick )中启动。

我的问题是,如果用户在macros仍在运行时再次双击,macros将在第一次执行完成后立即重新启动,无论我在macros运行时是否禁用了ListBox。

代码和testing

 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 

看起来像Excellogging/队列ListBox1_DblClick事件(为将来执行),而关联的列表框被禁用 。 为什么 ? 我怎样才能防止这个?

我也试过没有成功:

  • lockingMe.ListBox1.Locked = True
  • Doevents :在Me.ListBox1.Enabled = False之后添加DoEvents
  • EnableEventsApplication.EnableEvents = False
  • macroLaunchedvariables :使用一个variables来检查macros是否已经启动(在ListBox1_DblClick事件的开始处macroLaunched = True ,最后是macroLaunched = False )。 这是行不通的,因为在第一个事件结束之后启动第二个执行(因此variables设置为False )。 (并且在Dbl_Click事件的范围之外将variables设置回False是不可接受的,因为用户需要能够立即再次启动macros(但不是在第一个执行仍在运行的时候))。
  • 添加延迟 (仅用于testing目的):我在launch_macro后面添加了10秒延迟(Application.Wait)。 然后我在1秒内双击两次。 第二次执行仍然启动。 我通过日志logging进行检查:在第一个事件之后,第二个ListBox1.Dbl_Click事件由Excel 12s“logging”。

注意 :我正在使用Office Standard 2013

目前“解决scheme”

这个技巧是适应(减less延迟)从ASH答案:

 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 

虽然我不喜欢ListBox1仍然启用,Excel仍然排队等待事件,因此我需要估计用户可能有多less次Dbl_Click(取决于macros需要多长时间)来估计我需要的很多延迟(目前0.5秒能够处理(并logging)至less10个取消的事件)。 另外,在macros运行时,Excel似乎并不喜欢(关于性能)队列事件。

那么我会张贴我的build议,我希望你尝试一下,因为可能会被误解。 这个想法是,一旦macros完成,我们设置延迟n秒(比如2秒),然后再处理双击事件。 通过这种方式,在macros执行过程中排队的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 

您可以使用一个variableslocking代码的关键部分一段时间。 下面的示例lockingExcel工作簿的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