В процессе разработки на платформе 1С, особенно при создании интерактивных панелей мониторинга, торговых терминалов или систем реального времени, возникает необходимость обновлять данные на форме чаще, чем один раз в секунду. Стандартный механизм ПодключитьОбработчикОжидания при обычном использовании имеет ограничение в 1 секунду для циклического выполнения. Однако, существуют способы обойти это ограничение. В этой статье мы подробно разберем, как реализовать «быстрый» таймер в обычных формах, проанализируем риски и рассмотрим альтернативные методы.
Разберем самый простой и элегантный способ, который предоставляется самой платформой 1С. Согласно синтакс-помощнику, если мы хотим использовать период менее одной секунды (дробное число, например, 0.1 или 0.5), параметр Однократно метода ПодключитьОбработчикОжидания обязательно должен принимать значение Истина. Это означает, что система выполнит процедуру один раз и «забудет» о ней.
Чтобы превратить этот разовый вызов в постоянный цикл, мы применим логику рекурсивного переподключения. Проанализируем пример кода:
// Процедура в модуле формы
Процедура ПриОткрытии()
// Запускаем первый такт нашего таймера
ПодключитьОбработчикОжидания("ВыполнитьБыстроеОбновление", 0.2, Истина);
КонецПроцедуры
Процедура ВыполнитьБыстроеОбновление() Экспорт
// Здесь выполняем полезную работу: получение данных, расчеты
ПолучитьДанныеИзБазы();
// В самом конце процедуры снова подключаем этот же обработчик
// Это создаст эффект непрерывного цикла с интервалом 0.2 сек
ПодключитьОбработчикОжидания("ВыполнитьБыстроеОбновление", 0.2, Истина);
КонецПроцедуры
Рассмотрим подробнее, почему это работает. Платформа 1С позволяет задавать дробные значения для интервала, но не разрешает ставить их на «автоповтор», чтобы избежать случайного зацикливания интерфейсного потока при ошибках. Переподключая обработчик в конце выполнения процедуры, мы гарантируем, что следующий такт начнется только после того, как завершится предыдущий. Это защищает систему от «наложения» вызовов друг на друга.
Иногда требуется более гибкое управление паузами или выполнение действий, не блокирующих основной поток (насколько это возможно в рамках однопоточности 1С). Для этого можно привлечь системные компоненты Windows. Рассмотрим вариант с WScript.Shell или MSScriptControl.ScriptControl.
Этот метод позволяет использовать функцию Sleep из VBScript или JavaScript. Однако, стоит помнить, что прямое использование Sleep в основном потоке 1С приведет к полному замиранию интерфейса. Поэтому данный подход чаще используется в связке с внешними событиями или асинхронными вызовами скриптов.
Пример логики (схематично):
MSScriptControl.ScriptControl.Важное замечание: Использование MSScriptControl на 64-битных системах требует регистрации специальных библиотек или использования 32-битного клиента 1С, что делает этот способ менее универсальным по сравнению с первым.
Выясним причину, по которой этот метод считается одним из самых стабильных для высокоточного обновления. Поле HTML-документа на форме 1С — это полноценный браузерный движок. Внутри него можно запустить JavaScript, который обладает собственным высокоточным таймером setInterval.
Рассмотрим алгоритм реализации:
ПолеHTMLДокумента.
window.setInterval(function(){
// Генерируем событие для 1С
location.href = "v8action:UpdateData";
}, 100); // 100 миллисекунд = 10 раз в секунду
ПриНажатии (или аналогичное, в зависимости от версии платформы и типа события) у поля HTML-документа.Этот метод позволяет добиться частоты обновления вплоть до 20-50 раз в секунду без существенного влияния на отзывчивость кнопок и полей ввода, так как таймер работает внутри движка отрисовки HTML.
Проанализируем ситуацию: мы добились срабатывания кода 10 раз в секунду. Но увидит ли это пользователь? В 1С данные на форме обновляются автоматически в конце выполнения процедур или при простое системы. При высокой частоте вызовов нам может потребоваться принудительное обновление.
Для этого используется метод ЭтаФорма.Обновить(). Внимание! Вызов этого метода слишком часто (например, каждые 0.05 сек) приведет к тому, что процессор будет загружен на 100%, а пользователь не сможет даже нажать на кнопку, так как интерфейс будет постоянно занят перерисовкой.
Рекомендуем придерживаться следующих правил:
ЭтаФорма.Обновить() попробуйте просто изменять значение конкретного реквизита.Важно помнить критическую особенность платформы 1С: в обычных формах любой обработчик ожидания (включая штатный ПодключитьОбработчикОжидания) полностью останавливается, если на экране открыто модальное окно. Если ваш пользователь откроет окно выбора файла, предупреждение или модальную форму подбора, ваш таймер перестанет работать до тех пор, пока окно не будет закрыто. Если непрерывность процесса критична, следует полностью отказаться от использования модальности в конфигурации (перейти на блокирующие окна или использовать асинхронные методы).
Мы рассмотрели три основных подхода к созданию быстрых таймеров. Самым надежным и рекомендуемым для среды 1С является Способ 1 — рекурсивное использование штатной функции с параметром Однократно = Истина. Он не требует внешних компонент и легко отлаживается. Способы с HTML и COM-объектами стоит рассматривать только в специфических случаях, когда штатных возможностей интерфейсного потока становится недостаточно.