我有以下宏。作为简短描述,每次选择一个新单元格时,它会将参考文本作为滚动文本放在状态栏中。我做到了,因此不会通过将“ Do ... While循环”与“ Do events”一起使用来干扰用户输入,将共享以下代码。 问题是如果我快速单击多个单元格,它会记住以前的循环并全部运行。如何设置宏以停止运行除最后一个循环以外的所有循环?
Option Explicit
Public STATUSTEXT As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
STATUSTEXT = "Some text valid only for current selection"
'FILL THE TEXT AND GOTO EXIT SUB TO SKIP RELEASING STATUSBAR
charTotal = Len(STATUSTEXT)
charI = 1
Do
charI = charI + 1
Application.statusBar = Right(STATUSTEXT, charI)
DoEvents '@ IMPORTANT
Loop Until charI >= charTotal
Application.statusBar = STATUSTEXT
End Sub
答案 0 :(得分:1)
好吧,我会尝试更好地解释实际情况。
您的向下箭头会触发事件Worksheet_SelectionChange
。然后,该宏运行并进入DoEvents
循环。此DoEvents
允许您再次移动光标并执行其他事件。这意味着您的第一个SelectionChange
实际上在DoEvents
时停止了,而第二个SelectionChange
则触发了。在第二个事件完成后,您将返回到第一个DoEvents
事件的SelectionChange
,并一直持续到结束。
因此,由于VBA无法进行多线程处理,因此您的事件会堆积很多。它只是在DoEvents
处暂停第一个宏,从而触发下一个事件,并在执行以下操作后继续第一个事件:
1. SelectionChange
2. SelectionChange
3. SelectionChange
…
3. SelectionChange Ends
2. SelectionChange Ends
1. SelectionChange Ends
所以看起来第一个SelectionChange
事件最后运行是因为它在其他事件之间运行。请注意,这不是多线程处理,代码已暂停。
实际问题出在您的DoEvents
(如果删除)。 Excel会阻塞用户界面,直到第一个SelectionChange
事件结束为止,并且直到第一个事件结束之前才允许运行其他事件。而且,您会看到它在光标停止处结束。但这很慢,因为它等待事件直到执行向下的下一个箭头。
因此,实际上,您只需要取消第一个事件,以防另一个事件运行。请尝试以下操作:
Option Explicit
Public GlobalStatusText As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim PrivateStatusText As String
PrivateStatusText = "Some text valid only for current selection " & Target.Address
GlobalStatusText = PrivateStatusText
Dim charTotal As Long, charI As Long
charTotal = Len(GlobalStatusText)
charI = 1
Do
charI = charI + 1
Application.StatusBar = Right(GlobalStatusText, charI)
DoEvents '@ IMPORTANT
If GlobalStatusText <> PrivateStatusText Then Exit Sub 'cancel because another event run inbetween
Loop Until charI >= charTotal
Application.StatusBar = GlobalStatusText
End Sub
如果另一个事件在其间更改了状态文本,则将取消先前的事件。