Vba doevents что это
Функция DoEvents.
Обычно программист ожидает, что Windows (и Visual Basic) постоянно отслеживает все события и реагирует на них. С другой стороны, много времени уходит на различного рода вычисления или сортировку данных. Однако при этом не всегда желательно запрещать приложению Visual Basic реагировать на события. Если создается процедура, в которой много времени будет занято различного рода вычислениями, необходим механизм отслеживания состояния операционной системы и реагирования на различного рода события.
Функция, выполняющая такого рода задачи, носит название DoEvents. В каком бы месте программы ни стоял данный оператор, он сигнализирует Visual Basic о том, что управление передано операционной системе для обработки всех событий. (Windows сохраняет последовательность наступления событий в очереди, а также нажатий клавиш в очереди SendKeys.) DoEvents нельзя использовать в процедуре обработки событий, которая вызывается несколько раз. Например, процедура обработки событий Click может быть вызвана еще раз щелчком мыши. Если забыть про это, можно легко организовать в программе бесконечный цикл.
Цикл, работающий только в случае отсутствия каких-либо событий, носит наименование цикла ожидания. Такие циклы создаются внутри специализированной процедуры Sub, носящей имя Main, и подключающейся к любому программному модулю. В каждом проекте существует только одна процедура Main. Ее формат следующий:
Далее необходимо сделать так, чтобы модуль с Main загружался первым. Для этого нужно выбрать в меню пункт Project|Project Properties и затем страницу General. На этой странице выбрать и открыть список StartUp Object и выбрать Sub Main вместо формы. После того как процедура Main указана загрузочной. Visual Basic не будет автоматически загружать какую-нибудь форму. Для этого теперь необходимо писать программный код, используя, сервированные слова Load и Show.
Ниже приведен простой пример цикла ожидания. Необходимо создать новый проект и добавить к нему программный модуль. Далее в нем объявляется глобальная переменная Counter типа long integer:
Теперь добавим несколько строк кода к процедуре Main:
В завершение установим Sub Main, как загрузочный модуль, и добавим процедуру Form_Click:
После запуска такой программы счетчик будет увеличиваться каждый раз после щелчка внутри формы. Причина состоит в том, что в течение периода ожидания (когда пользователь не щелкает мышью) Visual Basic переходит к процедуре Main и добавляет 1 к счетчику. Поскольку Counter является глобальной переменной, ее значение сохраняется между вызовами процедуры.
Функция DoEvents на самом деле возвращает число форм, загруженных приложением в текущий момент. Цикл ожидания останавливается, когда выгружены все формы. (Или Visual Basic встречает оператор End.)
Другое общее использование функции DoEvents внутри функции состоит в запуске больших по времени вычислений. Установка цикла ожидания позволяет Visual Basic реагировать на события в момент вычислений. Небольшое дополнительное время при этом с лихвой окупается.
DoEvents function
Yields execution so that the operating system can process other events.
Syntax
DoEvents( )
Remarks
The DoEvents function returns an Integer representing the number of open forms in stand-alone versions of Visual Basic, such as Visual Basic, Professional Edition. DoEvents returns zero in all other applications.
DoEvents passes control to the operating system. Control is returned after the operating system has finished processing the events in its queue and all keys in the SendKeys queue have been sent.
DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file. For long-running processes, yielding the processor is better accomplished by using a Timer or delegating the task to an ActiveX EXE component. In the latter case, the task can continue completely independent of your application, and the operating system takes care of multitasking and time slicing.
Any time you temporarily yield the processor within an event procedure, make sure the procedure is not executed again from a different part of your code before the first call returns; this could cause unpredictable results. In addition, do not use DoEvents if other applications could possibly interact with your procedure in unforeseen ways during the time you have yielded control.
Example
This example uses the DoEvents function to cause execution to yield to the operating system once every 1000 iterations of the loop. DoEvents returns the number of open Visual Basic forms, but only when the host application is Visual Basic.
See also
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Vba doevents что это
Возможно, в созданных тобой прекрасных проектах есть процедуры, выполняющие длительные по времени циклы: сортировки, считавание или запись данных, поиск файлов и т.п. И если во время их выполнения ты заметил, что не можешь подвинуть свою форму по экрану, а другие, открытые окна оставляют на ней белые области (форма не обновляется), то тебе в самый раз прочитать про функцию DoEvents. Если же ты ничего такого не замечал, то значит еще заметишь. Но использование нижеследующей функции необходимо.
Для того, чтобы твое приложение, имеющее длинные циклы, не мешало пользователю на время их выполнения заняться другой работой, временно передвинув или даже свернув твою красивую форму, в нашем могучем арсенале имеется невостребованная пока функция 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.
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
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
‘В процедуре таймера мы просто имеем счетчик, который увеличивается
‘ на единицу при каждом включении, т. е. каждую миллисекунду.
Dim Flag As Boolean
В процедуре Command1_Click, прямо в самом начале установим начальное для цикла значения флага:
а в самом цикле поставим условие на выход
If Flag = True Then Exit Sub
Теперь, для выхода из цикла надо просто изменить значение флага False на True. Это мы и сделаем в процедуре Command2_Click:
Private Sub Command2_Click()
Flag = True
Text3 = «Цикл прерван»
End Sub
Вот и готово. Теперь наша кнопка Command2 прерывает цикл. Скачать исходник примера можно вверху страницы.
С помощью функции 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
Процедура Command1_Click() управляет флагом и выключает таймер
Private Sub Command1_Click()
Timer1.Enabled = False
Flag = True
End Sub
Скачать исходник этого примера можно отсюда.
Функция DoEvents
Примечание: Функция, метод, объект или свойство, описанные в данном разделе, отключаются, если служба обработки выражений Microsoft Jet выполняется в режиме песочницы, который не позволяет рассчитывать потенциально небезопасные выражения. Для получения дополнительных сведений выполните в справке поиск по словам «режим песочницы».
Функция передает управление операционной системе для обработки других событий.
Функция 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 doevents что это
Передает управление операционной системе для обработки других событий. Функция DoEvents возвращает значение типа Integer, представляющее число открытых форм в независимо установленных версиях языка Visual Basic. Во всех других приложениях функция DoEvents возвращает нуль.
DoEvents передает управление операционной системе. Управление возвращается после завершения обработки операционной системой всех событий из своей очереди и после передачи всех нажатий клавиш из очереди SendKeys. Если часть программы занимает основное процессорное время, следует периодически использовать функцию DoEvents для отказа от управления в пользу операционной системы, чтобы такие события как ввод с клавиатуры и нажатия кнопок мыши могли быть обработаны без существенной задержки.
Функция не имеет никаких параметров.
Проверьте, что процедура, в которой имеет место отказ от управления с помощью функции DoEvents, не выполняется вновь из другой части программы до возврата управления после первого вызова DoEvents. Это может привести к непредсказуемым результатам. Кроме того, не следует использовать функцию DoEvents, если другие приложения могут взаимодействовать с данной процедурой непредсказуемым способом во время передачи управления системе.
‘в данном примере функция DoEvents используется для передачи
‘управления операционной системе каждый раз после выполнения
‘1000 итераций цикла. DoEvents возвращает число открытых форм
‘Visual Basic, однако только в том случае, если главным приложением
‘является Visual Basic.
‘создает переменную для хранения числа загруженных и видимых форм Visual Basic.
Dim I, OpenForms
For I = 1 To 150000 ‘начало цикла.
If I Mod 1000 = 0 Then ‘если цикл выполнен 1000 раз.
OpenForms = DoEvents ‘передает управление операционной системе.
End If
Next I ‘увеличивает счетчик цикла
Купить перчатки спилковые драйвер по низкой цене с доставкой по Москве.
Каталог мебельного магазина и производителя мебели в Новокузнецке.