В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача выполнения определенных действий на стороне клиента в строго заданное время. Это может быть открытие формы отчета, запуск интерактивной обработки для кассира или вывод важного оповещения. Основная сложность заключается в том, что стандартный механизм регламентных заданий работает исключительно на стороне сервера и не имеет прямого доступа к пользовательскому интерфейсу (клиентскому контексту).
В данной статье мы разберем, как элегантно решить эту задачу, избегая использования внешних bat-файлов, скриптов или перезапуска системы, что особенно критично при работе с подключенным торговым оборудованием. Мы проанализируем наиболее надежные методы реализации этой функциональности штатными средствами встроенного языка.
Прежде чем перейти к решению, проанализируем ситуацию. Регламентные задания в 1С исполняются в фоновом сеансе на сервере. У этого сеанса нет экрана, нет форм и нет возможности вызвать метод ОткрытьФорму(). Если ваша задача требует взаимодействия с пользователем или использования торгового оборудования, инициализированного в текущем сеансе, единственным выходом будет использование механизмов, работающих непосредственно в клиентском приложении.
Наиболее эффективным и штатным способом запуска кода по расписанию на клиенте является метод ПодключитьОбработчикОжидания. Рассмотрим по шагам, как правильно реализовать эту логику, чтобы она работала стабильно и не нагружала систему.
Разберем алгоритм действий. Нам необходимо инициировать проверку времени при старте системы и выполнять её с определенной периодичностью.
Шаг 1. Инициализация в модуле управляемого приложения
Для того чтобы механизм заработал сразу после входа пользователя в программу, нам нужно прописать вызов обработчика в процедуре ПриНачалеРаботыСистемы. Если вы работаете в типовой конфигурации (например, БП 3.0), рекомендуется делать это через расширение, чтобы сохранить поддержку конфигурации.
Проанализируем пример кода в модуле управляемого приложения:
Процедура ПриНачалеРаботыСистемы()
// Подключаем проверку времени раз в 60 секунд
ПодключитьОбработчикОжидания("ПроверитьВремяДляЗапускаФормы", 60);
КонецПроцедуры
Шаг 2. Создание процедуры обработчика
Процедура, имя которой мы указали в кавычках (в нашем примере ПроверитьВремяДляЗапускаФормы), должна располагаться либо в самом модуле управляемого приложения, либо в общем модуле с установленными флагами Клиент (управляемое приложение).
Выясним причину выбора интервала в 60 секунд. Если мы будем проверять время слишком часто (например, каждую секунду), это создаст лишнюю нагрузку. Интервал в одну минуту является оптимальным для задач, привязанных к конкретному часу и минуте.
Просто сравнить текущее время с целевым недостаточно. Если программа обнаружит, что сейчас 12:00, она будет открывать форму каждую минуту в течение всей этой минуты. Нам нужно предусмотреть защиту от многократного открытия.
Рассмотрим подробнее реализацию безопасного обработчика:
Перем ПоследняяДатаЗапуска Экспорт; // Глобальная переменная в модуле приложения
Процедура ПроверитьВремяДляЗапускаФормы() Экспорт
ТекущаяДата = ТекущаяДата();
НужноеВремя = НачалоДня(ТекущаяДата) + (12 * 3600); // 12:00:00
// Проверяем, наступило ли время и не запускали ли мы форму сегодня
Если ТекущаяДата >= НужноеВремя И НачалоДня(ПоследняяДатаЗапуска) <> НачалоДня(ТекущаяДата) Тогда
// Дополнительная проверка: открываем форму только нужному пользователю
Если ПользователиИнформационнойБазы.ТекущийПользователь().Имя = "Кассир1" Тогда
ОткрытьФорму("ОбщаяФорма.МояСпециальнаяФорма");
ПоследняяДатаЗапуска = ТекущаяДата;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В данном примере мы используем переменную ПоследняяДатаЗапуска для фиксации факта срабатывания. Это гарантирует, что форма откроется ровно один раз в сутки.
Иногда требуется, чтобы время запуска определялось на сервере (например, администратор меняет расписание в пользовательском интерфейсе). В этом случае удобно использовать связку из регистра сведений и обработчика ожидания.
ОчередьЗаданийКлиента. В нем будут храниться поля: Пользователь, ИмяФормы, Выполнено.Выполнено = Истина.Посмотрим на пример клиентского кода для такого подхода:
Процедура ПроверитьОчередьЗаданийИзРегистра() Экспорт
ПараметрыОтбора = Новый Структура("Пользователь, Выполнено", ПараметрыСеанса.ТекущийПользователь, Ложь);
ЗаписьЗадания = РегистрыСведений.ОчередьЗаданийКлиента.Выбрать(ПараметрыОтбора);
Пока ЗаписьЗадания.Следующий() Цикл
// Открываем форму
ОткрытьФорму(ЗаписьЗадания.ИмяФормы);
// Отмечаем выполнение на сервере
ЗафиксироватьВыполнениеЗадания(ЗаписьЗадания.КлючЗаписи);
КонецЦикла;
КонецПроцедуры
Автор темы справедливо заметил, что запуск нового сеанса нежелателен из-за конфликтов с торговым оборудованием. Метод с ПодключитьОбработчикОжидания полностью решает эту проблему, так как код выполняется в рамках уже запущенного сеанса, где оборудование уже инициализировано и готово к работе.
Важный момент: Если форма должна взаимодействовать с кассовым аппаратом (ККТ), убедитесь, что обработчик ожидания не прерывает критически важные операции пользователя. Платформа 1С устроена так, что обработчик ожидания не сработает, пока открыто модальное окно или выполняется другой длительный процесс на клиенте, что обеспечивает дополнительную безопасность.
Если вы используете современную конфигурацию на базе Библиотеки стандартных подсистем (БСП), например Бухгалтерию предприятия 3.0, проанализируйте возможность интеграции в механизм Текущие дела. Это позволит не просто открывать форму «в лоб», а выводить уведомление в панели текущих дел, которое пользователь сможет нажать в удобный момент. Однако для жесткого запуска в 12:00 описанный выше метод с обработчиком ожидания остается самым надежным и простым в реализации.
Подведем итог: использование ПодключитьОбработчикОжидания в модуле управляемого приложения — это наиболее гибкий инструмент для автоматизации клиентских действий. Он позволяет соблюсти точность по времени, избежать конфликтов с драйверами оборудования и не требует внесения изменений в инфраструктуру сервера.