Doevents vba excel как использовать

Обновлено: 07.07.2024

Примечание: Функция, метод, объект или свойство, описанные в данном разделе, отключаются, если служба обработки выражений Microsoft Jet выполняется в режиме песочницы, который не позволяет рассчитывать потенциально небезопасные выражения. Для получения дополнительных сведений выполните в справке поиск по словам "режим песочницы".

Функция передает управление операционной системе для обработки других событий.

DoEvents ( )

Функция DoEvents возвращает целое число, представляющее количество открытых форм в автономных версиях Microsoft Visual Basic, таких как Visual Basic Professional Edition. Функция DoEvents возвращает нуль для всех других приложений.

DoEvents передает управление операционной системе. Управление возвращается по завершении обработки очереди событий операционной системой и отправки всех значений из очереди SendKeys.

Функция DoEvents наиболее удобна при выполнении простых задач, таких как предоставление пользователю возможности прервать запущенный процесс (например, поиск файла). При обработке продолжительных процессов рекомендуется для передачи управления использовать событие "Таймер" или делегирование задачи компоненту ActiveX EXE. В последнем случае выполнение задачи может продолжаться совершенно независимо от приложения, а многозадачность и управление временем процессора осуществляется операционной системой.

Каждый раз, когда вы временно возвращаетесь к процессору в процедуре обработки события, убедитесь, процедура не выполняется повторно из другой части кода до первого звонка; это может привести к непредсказуемым результатам. Кроме того, не используйте doEvents, если другие приложения могли взаимодействовать с вашей процедурой непредвиденным образом в период, когда вы укатиле управление.

Пример

Примечание: В примерах ниже показано, как использовать эту функцию в модуле Visual Basic для приложений (VBA). Чтобы получить дополнительные сведения о работе с VBA, выберите Справочник разработчика в раскрывающемся списке рядом с полем Поиск и введите одно или несколько слов в поле поиска.

В этом примере функция DoEvents используется для передачи управления операционной системе через каждую тысячу итераций цикла. Функция DoEvents возвращает количество открытых форм Visual Basic при условии, что ведущим приложением является Visual Basic.


Когато пишем огромни кодове, винаги попадаме в капана на VBA. Когато кодът е голям, VBA отделя време, за да завърши процеса на изпълнение и изпълнение. Което може да отнеме време от минута до няколко минути. Това е времевата рамка, когато всички се дразнят. И не можем да направим нищо друго в този период от време. Но за да избегнем това, имаме функция във VBA, наречена DoEvents. С помощта на DoEvents можем да стартираме кода на заден план и едновременно с това можем да правим и други видове неща. Ние не можем да работим само върху друг инструмент или софтуер, но също така можем да прекъснем кода или да спрем между процеса на изпълнение.

След като въведем DoEvents в кода, след това освен VBA, ще имаме и контрола на работата, която искаме да вършим. Хубавото на DoEvents е, че няма никакъв синтаксис за писане. Можем директно да поставим Doevents там, където искаме да поемем контрола над VBA и да изпълняваме задачите според нашите нужди.

Как да използвате функцията DoEvents в Excel VBA?

По-долу са различните примери за използване на функцията DoEvents в excel, използвайки VBA код.

Можете да изтеглите този шаблон на VBA DoEvents Excel тук - VBA шаблон на DoEvents Excel

Excel VBA DoEvents - Пример №1

Въпреки че, за да изпълним DoEvents, се нуждаем от огромен набор от данни, където можем да видим как кодът се прекъсва. Така че, ще използваме цикъл, при който числата ще се прилагат, докато кодът не бъде завършен. За това следвайте стъпките по-долу:

Стъпка 1: Отворете модул в VBA от раздел Вмъкване на менюто, както е показано по-долу.


Стъпка 2: Напишете подпроцедурата на VBA DoEvents или можем да изберем всяко име, за да определим кода според нашите нужди.

Код:


Стъпка 3: Сега дефинирайте променлива във всяко име с типове данни Long. Целта на разглеждането на типа данни като Дълга е, защото ще приемаме всякаква дължина от данни, която искаме, което не е възможно, ако вземем предвид Integer.

Код:


Стъпка 4: Сега отворете контур For-Next, където ще поставим условията.

Код:


Стъпка 5: Помислете за обхвата на избрания от вас брой, който може да бъде видян при изпълнението. Тук приемаме диапазона 1 до 2000 в дефинирана променлива А.

Код:


Стъпка 6: След като определим диапазона от числа, ще изберем диапазона от клетки, където ще видим промените в числата, които сме избрали по-горе. Да речем, че обхватът на клетките е от А1 до А5. Това може да бъде и една клетка.

Код:


Стъпка 7: Сега стартирайте кода, като кликнете върху бутона Play, разположен под лентата на менюто.

Ще видим, кодът завърши с отпечатването на числата от 1 до 20000, но не можахме да го спрем.

Стъпка 8: За да получите пълен контрол върху кода, приложете DoEvents след условията на цикъл, както е показано по-долу.

Код:


Стъпка 9: Сега отново стартирайте кода. И в този момент се опитваме да спрем кода, като щракнем върху бутона за спиране, ще забележим, че кодът ще бъде спрян между процесите, преди да завърши пробната версия на 20000.

Excel VBA DoEvents - Пример №2

Има и друг тип процес за внедряване на DoEvents. Но за това също ще ни трябва огромен код, както се вижда в пример-1. За това следвайте стъпките по-долу:

Стъпка 1: Напишете подпроцедурата на VBA DoEvents, както е показано по-долу.

Код:


Стъпка 2: Отворете директно цикъл For-next, без да дефинирате променлива.

Код:


Стъпка 3: Изберете диапазон от числа, който ще видим да работи. Нека диапазонът е 1 до 20000 същият като пример-1.

Код:


Стъпка 4: Сега директно поставете каквато и да е работа за изход, да речем, че изходът е както е показано по-долу. И диапазонът на стойностите ще бъде +1 от действителната стойност.

Код:


Стъпка 5: Сега изберете диапазона, в който искаме да видим изхода. Нека клетката е A1.

Код:


Стъпка 6: И най-накрая ще поставим DoEvents в края на условието за цикъл.

Код:


Стъпка 7: И след това стартирайте кода, като натиснете клавиша F5. Ще видим, можем да направим всичко, дори когато кодът работи. За демонстрация съм избрал клетките B1 и C1. Цифрите достигнаха само при 4348, което е доста по-малко от лимита, който поставихме.


Стъпка 8: Ако премахнем DoEvents и стартираме кода, няма да можем да направим нищо, докато кодът не завърши процеса си. Да видим и това.

Код:


Стъпка 9: Сега стартирайте кода отново. Както виждаме, докато се опитвахме да кликнем върху Stop, кодът не спря. А функцията Play все още беше включена.

Плюсовете и минусите на Excel VBA DoEvents

  • Можем да работим върху всеки инструмент или файл във фонов режим, докато VBA кодът ще работи паралелно.
  • Използването на DoEvents не ни спира да вършим работата, която искаме, когато кодът работи.
  • Той презаписва работния лист или работната книга, когато превключваме между различните работни листове или работна книга.
  • Кодът спира, когато напишем или променим клетката за момент и не получаваме известие.

Неща, които трябва да запомните

  • Ако направим нещо, без да прилагаме DoEvents, тогава има голяма възможност кода да направи системата и файла замразени. И че или ще възобновим файловете, след като кодът е напълно стартиран, или ще сринем файла с множество кликвания.
  • Можем да видим промяната в процеса, докато работим по другата работа едновременно.
  • След като попълним кода, запишете файла във формат excel с активиран макрос, за да избегнете загуба на код.
  • Опитайте да приложите кода в огромен и голям набор от кодиране, там ще видим реалната имплементация и употреба.

Препоръчителни статии

Това е ръководство за VBA DoEvents. Тук обсъждаме как да използвате функцията DoEvents в Excel, използвайки VBA код, заедно с практически примери и шаблон за изтегляне на excel. Можете да разгледате и другите ни предложени статии -

Путеводитель по VBA Date. Здесь мы обсудили, как использовать функцию даты VBA Excel с практическими примерами и загружаемым шаблоном Excel.…

Формат даты VBA

Руководство по формату даты VBA. Здесь мы обсудим, как использовать функцию формата даты VBA в Excel, а также несколько практических примеров и загружаемый шаблон Excel.…

VBA DateAdd

Руководство по VBA DateAdd. Здесь мы обсуждаем примеры функции VBA DateAdd для добавления и вычитания дней, месяцев и лет из заданной даты с примерами.…

VBA DatePart

Руководство по VBA DatePart. Здесь мы обсудим, как использовать функцию DatePart в Excel с использованием кода VBA, а также с практическими примерами и загружаемым шаблоном Excel.…

VBA DateValue

Руководство по VBA DateValue. Здесь мы обсудим, как использовать функцию Excel VBA DateValue вместе с практическими примерами и загружаемым шаблоном Excel.…

VBA объявить массив

Руководство по VBA объявить массив. Здесь мы обсудим, как объявить массив в Excel с использованием кода VBA, а также с практическими примерами и загружаемым шаблоном Excel.…

VBA DateSerial

Руководство по VBA DateSerial. Здесь мы обсудим, как использовать функцию Excel VBA DateSerial вместе с практическими примерами и загружаемым шаблоном Excel.…

VBA Debug Print

Руководство по VBA Debug Print. Здесь мы обсудим, как использовать Debug Print в Excel с использованием кода VBA, а также с практическими примерами и загружаемым шаблоном Excel.…

VBA DateDiff

Руководство по VBA DateDiff. Здесь мы обсудим, как использовать функцию DateDiff в Excel VBA вместе с практическими примерами и загружаемым шаблоном Excel.…

VBA Удалить столбец

Руководство по VBA Удалить столбец. Здесь мы обсудили, как удалить столбец в Excel, используя VBA с практическими примерами и загружаемым шаблоном Excel.…

VBA Удалить файл

Руководство по удалению файла VBA. Здесь мы обсудим, как использовать Excel VBA Delete File вместе с несколькими практическими примерами и загружаемым шаблоном Excel.…

VBA Удалить лист

Руководство по VBA Удалить лист. Здесь мы обсудим, как удалить лист в Excel VBA вместе с практическими примерами и загружаемым шаблоном Excel.…

Словарь VBA

Руководство по определению словаря и шагов VBA для создания словаря в Excel с использованием кода VBA вместе с загружаемым шаблоном Excel.…

VBA DoEvents

Руководство по VBA DoEvents. Здесь мы обсудим, как использовать функцию DoEvents в Excel, используя код VBA, а также приведем практические примеры и загружаемый шаблон Excel.…

VBA Dim

Руководство по VBA Dim. Здесь мы обсудили, как использовать Excel VBA Dim, а также несколько практических примеров и загружаемый шаблон Excel.…

VBA Do Loop

Руководство по VBA Do Loop. Здесь мы обсудим, как использовать Do Loop в Excel VBA вместе с практическими примерами и загружаемым шаблоном Excel.…

VBA Удалить строку

Руководство по VBA Удалить строку. Здесь мы обсудили, как удалить строку в Excel VBA с практическими примерами и загружаемым шаблоном Excel.…

VBA DIR

Руководство по функции VBA DIR. Здесь мы обсудим, как использовать функцию DIR в Excel VBA вместе с некоторыми практическими примерами и загружаемым шаблоном Excel.…

VBA Editor

Руководство по редактору VBA. Здесь мы обсудим, как открыть редактор Excel Visual Basic и его использование, включая строку меню, панель инструментов, окно проекта и окно свойств.…

VBA Double

Руководство по Excel VBA Double. Здесь мы обсудим, как использовать двойные типы данных в Excel VBA вместе с практическими примерами и загружаемым шаблоном Excel.…

Для того, чтобы твое приложение, имеющее длинные циклы, не мешало пользователю на время их выполнения заняться другой работой, временно передвинув или даже свернув твою красивую форму, в нашем могучем арсенале имеется невостребованная пока функция DoEvents, синтаксис которой приятно ласкает взгляд:
DoEvents()
и никаких тебе аргументов.

Эта функция, согласно мануалу, возвращает значение типа Integer, представляющее собой количество открытых форм, если фокус находится на форме Visual Basic и ноль, если фокус находится на окнах других приложений. Ну это кому что интересно. Главное это то, что эта функция передает управление операционной системе, то бишь Windows, для обработки других событий. И после обработки Windows'ом всех событий из очереди и передачи всех нажатий клавиш из очереди функции SendKeys возвращает управление обратно в Visual Basic.

Хотя в использовании этой функции нет особенных трудностей, учитывая специфику сайта, лучше один раз пощупать функцию в маленькой процедурке, чем искать ошибку в большом проекте.
Создадим Exe-проектик, положим на форму кнопку Command1 и текстбокс Text1и напишем маленькую процедурку:

Private Sub Command1_Click()
Dim x As Long
For x = 1 To 300000
Text1 = x
Next x
End Sub

Private Sub Command1_Click()
Dim x As Long
For x = 1 To 300000
Text1 = x
DoEvents
Next x
End Sub

Конечно мигание цифр не радует глаз. Кроме того, при передаче управления Windows выполнение программы Visual Basic (в нашем случае цикла) приостанавливается, но зато все наши проблемы мгновенно решились: и форму можно двигать и форма обновляется.
В связи с тем, что повторный вызов функции DoEvents в момент, когда функция еще не передала управление из операционной системы назад в Visual Basic может вызвать непредвиденные последствия, нежелательно вызывать процедуру DoEvents из других процедур программы. Видимо эти же соображения имеют место, когда предполагается, что нежелательно использовать функцию DoEvents в процедурах обработки событий Click. Но мне не удалось добиться никаких особенных фатальных результатов, кроме перезапуска цикла, даже беспрестанно кликая по кнопке Command1.

Основным недостатком этой функции является очень значительное уменьшение быстродействия в длинных по времени циклах (в коротких ее вообще нет смысла использовать). Самое простое решение этого вопроса - запуск DoEvents не при каждой итерации, а например, при каждом сотом (или тысячном) проходе цикла, в зависимости от его параметров. Решить это можно, например, вводя дополнительную переменную-счетчик (в нашем примере y). С каждым проходом цикла счетчик увеличивается на единицу, а при достижении им значения, например 1000, вызывает функцию DoEvents и обнуляется, чтобы при дальнейшей работе цикла снова увеличится до 1000. Тогда наша процедура будет выглядеть следующим образом:

Private Sub Command1_Click()
Dim x As Long
Dim y As Long
For x = 1 To 300000
Text1 = x
y = y + 1
If y = 1000 Then 'проверяем счетчик итераций
'и если он совпадает с заданым числом, запускаем DoEvents и обнуляем счетчик
DoEvents
y = 0
End If
Next x
End Sub

Если тебя уже раздражает такое "ламерское" (но на мой взгляд удобное и наглядное решение), можно отследить тысячный проход цикла по-другому, например деля значения счетчика цикла x на эту тысячу с остатком (Mod) при каждой итерации, тогда при остатке ноль можно считать, что значение х кратно нашей тысяче. Тогда наш код будет выглядеть так:

Private Sub Command1_Click()
Dim x As Long
Dim y As Long
For x = 1 To 300000
Text1 = x
y = y + 1
If x Mod 1000 = 0 Then DoEvents 'получаем остаток от деления
'и если он равен нулю, запускаем DoEvents
Next x
End Sub


А может быть снижение быстродействия не так уж и значительно и им можно пренебречь? Чтобы нам не принимать все на веру, мы сами проведем соответствующее сравнительное исследование зависимости быстродействия от частоты срабатывания функции DoEvents. Для этого нам на форме дополнительно понадобятся Timer1, и еще два текстбокса Text2 и Text3. В уже имеющийся Text1 мы будем вводить интервал цикла (по умолчанию он у нас будет 300000), в Text2 - на какой итерации (1-ой, т.е. каждой, 100-ой, 10000-й и т.д ) будет включаться функция DoEvents. В Text3 выведем результат измерений в миллисекундах.
Объявим три переменных:

Option Explicit
Dim Iter As Long 'итерация срабатывания DoEvents
Dim RunTime As Integer 'время работы цикла
Dim RunLong As Long 'длина цикла

В процедуре Form_Load присвоим начальные значения цикла и итераций:

Private Sub Form_Load()
Text2 = 1
Text1 = 1000000
End Sub

Код процедуры Command1_Click Изменим следующим образом:

Private Sub Command1_Click()
Dim x As Long
Dim y As Long
Iter = Val(Text2) 'Присваиваем переменным значения для цикла
RunLong = Val(Text1)
RunTime = 0
Text3 = "Цикл в работе"
Timer1.Interval = 1 'устанавливаем интервал таймера в 1 мск
Timer1.Enabled = True 'запускаем таймер

For x = 1 To RunLong
'обратите внимание на то, что вывод значений переменной цикла X не выводится в Text1,
'так как это непомерные затраты времени и исказят наши значения.
'Text1 = x
y = y + 1
If y = Iter Then
DoEvents
y = 0
End If
Next x
Timer1.Enabled = False 'выключаем таймер
Text3 = RunTime 'выводим значение счетчика таймера в текстбокс
End Sub

'В процедуре таймера мы просто имеем счетчик, который увеличивается
' на единицу при каждом включении, т. е. каждую миллисекунду.

Используя эту функцию мы можем позволить пользователю прервать продолжительный процесс. Для этого достаточно ввести булеву переменную для флага, например Flag , которая и будет сигнализировать о том, что процесс необходимо прервать.
Добавим на форму кнопку Command2, которой и будем прерывать выполнение цикла. В секцию (General) добавим объявление флага

Dim Flag As Boolean

В процедуре Command1_Click, прямо в самом начале установим начальное для цикла значения флага:

Flag = False

а в самом цикле поставим условие на выход

If Flag = True Then Exit Sub

Теперь, для выхода из цикла надо просто изменить значение флага False на True. Это мы и сделаем в процедуре Command2_Click:

Private Sub Command2_Click()
Flag = True
Text3 = "Цикл прерван"
End Sub

С помощью функции DoEvents можно также организовать цикл ожидания, прерываемый пользователем. В качестве примера сделаем программку-шутку, которая иммитирует предупреждение пользователю о начале форматирования жесткого диска. Для этого в новом Exe-проекте на форме нам понадобится Label1, Command1 и Timer1.
Объявим пару переменных:

Option Explicit
Dim RunTime As Integer 'время в секундах
Dim Flag As Boolean 'флаг, сигнализирующей о прерывании цикла

Для процедуры, собственно, цикла ожидания я выбрал событие формы _Activate, так как оно возникает, когда форма уже загружена и инициализирована и элементы на ней видимы.

Private Sub Form_Activate()
RunTime = 10 'устанавливаем начальные значения секунд
Timer1.Interval = 1000 'интервал срабатывания таймера 1 сек
Timer1.Enabled = True ' включаем таймер
'организуем цикл, работающий до тех пор, пока переменная RunTime
'не стане равной нулю (изменяется таймером)
Do Until RunTime = 0
DoEvents 'постоянно передаем управление Windows
If Flag Then 'проверяется, нажата ли кнопка Command1 для
'прерывания цикла (Flag=True) или нет (Flag=False)
Label1 = "Молодец, успел, но все равно форматирование начинается!"
Exit Sub 'выход из процедуры, если кнопка Command1 нажималась
End If 'конец условия
Loop 'конец цикла
Timer1.Enabled = False 'выключение таймера
Label1 = "Не успел, не успел, надеюсь на винчестере ничего ценного нет?"
End Sub

В процедуре таймера при каждом срабатывании (ежесекундно) уменьшаем значение RunTime на единицу

Процедура Command1_Click() управляет флагом и выключает таймер

Читайте также: