问题
我有一个宏(我将其称为launch_macro
),通过在用户窗体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在关联的ListBox被禁用时记录/排队 ListBox1_DblClick 事件(以便将来执行)。为什么会这样?我该如何防止这种情况发生?
我也尝试了以下方法,但都没有成功:
- Locked :
Me.ListBox1.Locked = True
- Doevents :在 Me.ListBox1.Enabled = False
之后添加 DoEvents
- EnableEvents : Application.EnableEvents = False
- macroLaunched variable :使用变量检查宏是否已启动(在 ListBox1_DblClick
事件的开始处设置 macroLaunched = True
,在结束时设置 macroLaunched = False
)。由于第二次执行是在第一个事件结束之后启动的(因此变量被设置回 False
),因此这不起作用。 (而在Dbl_Click事件范围之外将变量设置回False是不可接受的,因为用户需要能够立即再次启动宏(但不能在第一次执行仍在运行时)。
- 添加延迟 (仅用于测试):我在启动macro后立即添加了10秒的延迟(Application.Wait)。然后我在1秒内双击了两次。第二次执行仍然启动。我通过日志记录:第二个ListBox1.Dbl_Click事件在第一个事件后12秒被“记录”到Excel中。
注意:我使用的是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
这个方法“可以解决问题”,但是我仍然不喜欢 ListBox1 仍然处于启用状态,而且 Excel 仍在排队事件,因此我需要估计用户可能会 Dbl_Click 的次数(取决于宏花费的时间),以估算我需要多少延迟(目前为0.5秒,以便能够处理(并记录)至少10个取消事件)。另外,似乎 Excel 在运行宏时不太喜欢(性能方面)排队事件。
EnableEvents
;它也不起作用。 :-( - TiboDoEvents
。记录日志的速度太快而不可能是问题所在,即使在开头添加Me.ListBox1.Enabled = False
仍然存在问题。我不明白为什么只有我会出现这个问题…… - Tibo