Проблема с OnTime

Программирование на Visual Basic for Applications
Estilla
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 118
Зарегистрирован: 27.09.2006 (Ср) 21:07
Откуда: Москва

Проблема с OnTime

Сообщение Estilla » 27.10.2006 (Пт) 10:35

У меня по нажатию кнопки стартует шедулер посредством OnTime на запуск процедуры каждые 30 секунд.
В модуле:
Код: Выделить всё

Public Sub ready()
dTime = Now + TimeValue("00:00:30")
Application.OnTime dTime, "ready"
Call Workbooks(strCurrentWbook).Worksheets("1").checkReady
End Sub

При определенном условии в любое время шедулер останавливается, запускаются парочка процедур, после чего вновь запускается старт этого шедулера при тех же условиях, что описаны мной вначале.
Процедуры старта и стопа шедулера:
Код: Выделить всё
Public Sub pStartCheckPrice()
dTime = Now + TimeValue("00:00:30")
Application.OnTime dTime, "ready"
End Sub

Код: Выделить всё

Public Sub pStopCheckPrice()
On Error Resume Next
Application.OnTime EarliestTime:=dTime, Procedure:="ready", Schedule:=False
End Sub

##################
Так вот, проблема в том, что на каком то моменте скрипт начинает запускаться чаще чем через 30 сек., тАкое ощущение, что шуделер не останавливается, а новый запуск плодит всё новый и новый шедулер и запусков становится несколько. В чем может быть трабла, скажите плиз?

Genyaa
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 17.10.2006 (Вт) 13:46

Re: Проблема с OnTime

Сообщение Genyaa » 27.10.2006 (Пт) 18:18

Так вот, проблема в том, что на каком то моменте скрипт начинает запускаться чаще чем через 30 сек., тАкое ощущение, что шуделер не останавливается, а новый запуск плодит всё новый и новый шедулер и запусков становится несколько. В чем может быть трабла, скажите плиз?

На сколько я понял представленный код, процедура "останова", действительно, не останавливает, а только переопределяет последний установленный запуск. Т.е. после Вашего "стопа" через 30 сек. пройдет новый запуск, но запуски не остановятся, а только "отложатся" на время, прошедшее после предыдущего запуска до этого "стопа". А процедура старта устанавливает новую "ветвь" запусков OnTime (как мне кажется, без Schedule:=False каждый объявленый OnTime отработается, вне зависимости был ли указан тот же макрос в параметрах).

Когда я делал периодические запуски через OnTime прекращение повторного запуска я делал через глабальный флаг (глабальную логическую переменную), которая проверялась всякий раз перед ининициализации OnTime. Отмену уже объявленного OnTime я не делал, но можно попробовать сделать Schedule:=False с EarliestTime и LatestTime меньшими, чем Now. Попробуйте, может быть получится. Если нет, нужно поставить влаг в сам запускаемый макрос ready, чтобы он не отрабатывался, если флаг поднят, и проверять этот флаг до повторного запуска OnTime (если поднят - не запускать). А для старта - опустить флаг и сделать OnTime.
Всякое решение плодит новые проблемы.

Pavel55
Обычный пользователь
Обычный пользователь
 
Сообщения: 90
Зарегистрирован: 27.10.2006 (Пт) 20:11

Сообщение Pavel55 » 27.10.2006 (Пт) 20:28

может эта тема поможет ?
http://www.developing.ru/forum/viewtopic.php?t=4925

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 27.10.2006 (Пт) 23:34

Предположим, что переменная dTime объявлена глобально... Если в файле есть две процедуры запускающие OnTime независимо друг от друга, и при этом обе используют одну и ту же глобальную переменную dTime, то почти наверняка будут накапливаться неотмененные шедулы, которые будут продолжать выстреливать, но со сдвигом по фазе. Дело в том, что для отмены запущенного OnTime необходимо чтобы параметры EarliestTime и Procedure были строго идентичны тем, которые использовались при запуске отменяемого шедула. Но если за это время кто-то/что-то переписало переменную dTime, то сам понимаешь... спутник навсегда остался на орбите :-)
Привет,
KL

Estilla
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 118
Зарегистрирован: 27.09.2006 (Ср) 21:07
Откуда: Москва

Сообщение Estilla » 28.10.2006 (Сб) 0:16

KL писал(а):Предположим, что переменная dTime объявлена глобально... Если в файле есть две процедуры запускающие OnTime независимо друг от друга,


Да если бы было так :)
В том то и дело. Что порядок следующий:
Запуск-Стоп-Запуск с одной переменной dTime.
Что еще замечено. Что "локально" всё работает как часы. А когда начинают приходить данные по DDE, то и возникает данная проблема.
Мне единстенно что сейчас начинает смущать тот факт, что я использую два раза
Код: Выделить всё
OnTime
в разных процедурах. Но яя так сделал по подобию как описывают в примерах, правда там один кусок с OnTime лепят в книгу (при ее открытии Workbook_Open), а я навесил на кнопку, но мне так и не понятно зачем нужно использовать два раза
Код: Выделить всё
OnTime

А в примере на который указал Pavel55 вообще не используется остановка OnTime посредством Schedule:=False, однако пашет.

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 28.10.2006 (Сб) 2:10

Estilla писал(а):Да если бы было так :)
Мне отсюда трудно судить так или не так, тем более не видя файла. Т.ч. ничего другого не остается как верить тебе на слово ;-)

Estilla писал(а):А в примере на который указал Pavel55 вообще не используется остановка OnTime посредством Schedule:=False, однако пашет.
Так там и не нужно, там механизм другой. Ты пойми следуещее:

1.) метод OnTime сам по себе никогда не повторяется, а всегда запускает разовый процесс, который, выстрелив один раз умирает навеки.

2.) параметр Schedule:=False убивает только уже запущенный, но еще не выстреливший процесс. Выстрелившему уже ничего не надо

3.) эффект повторяемости достигается не через OnTime как таковой, а через конструкцию макроса, который через опр. промежуток времени (устанавленный последним OnTime) вызовет сам себя и OnTime запустится опять - т.е. цепная реакция, переходящая в бесконеечный цикл (infinite loop).

4.) при каждом запуске процедур pStartCheckPrice и ready текущее значение переменной dTime стирается и присваивается новое

5.) процедуры pStartCheckPrice и ready запускаются не только видимо (т.е. нажатием твоей кнопки или событием Workbook_Open), но и невидимо - самим OnTime

6.) и так будет продолжаться пока не произойдет одно из трех:

- последний запущенный, но не выстреливший OnTime отменится с пом. Schedule:=False (принцип кода, который, в сильно измененном виде, пытаешься использовать ты)

- выстреливаемый самим OnTime макрос по какой-то причине возмет да и не запустит OnTime снова (см. условие If gate Then... в коде указанном Pavel55)

- Excel будет форсированно (через ошибку) закрыт

7.) теперь сам представь: что если ты, сам того не ведая, каждый раз запускаешь новый... нет не OnTime, а хуже - замкнутый цикл процедуры pStartCheckPrice, которая уже не требует твоей помощи, но и не подчиняется тебе, так как ты потерял от нее ключи, не имея возможности знать с каким значением переменной dTime был запущен текущий OnTime. И каждый раз, упустив этот, ты будешь запускать новый бесконечный цикл, а твоя процедура pStopCheckPrice будет стрелять по воробьям.

8.) но это еще не все. А что если и с процедурой ready происходит тоже самое?

Исходя из вышесказанного, ищи решение не в OnTime или DDE, а в организации процесса работы твоей программы. Я на 99.99% уверен в том, что, как я указывал в моем первом сообщении, две разные процедуры, использующие OnTime, обслуживаются одной и той же глобальной переменной, которую они вместе и поврозь модифицируют. Ищи утечку в процессе - твоя задача своевременно перекрыть кислород еще не выстрелившему OnTime пока переменная dTime не была изменена другим процессом. Или используй метод указанный Pavel55.
Привет,
KL

Estilla
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 118
Зарегистрирован: 27.09.2006 (Ср) 21:07
Откуда: Москва

Сообщение Estilla » 29.10.2006 (Вс) 19:10

ok. я понял. протестировал код указанный Pavel55, мне он больше подошел для моей замороченной задачи. Спасибо.


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 79

    TopList