Хорошо, я пытаюсь лучше объяснить, что на самом деле происходит.
Ваша стрелка вниз вызывает событие Worksheet_SelectionChange
. Затем этот макрос запускается и попадает в l oop с 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
Это отменит предыдущие события, если другое событие изменило текст состояния между ними.