Как реализовать периодические всплывающие уведомления в 1С через обработчик ожидания?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает задача информирования пользователя о важных событиях в режиме реального времени. Это могут быть напоминания о запланированных встречах, уведомления о новых задачах или сообщения о критических изменениях в базе данных. Для реализации такого функционала в системе «1С:Предприятие 8.3» используется механизм обработчиков ожидания. В этой статье мы подробно разберем, как правильно настроить периодическую проверку данных, создать удобный интерфейс для пользователя и избежать типичных ошибок производительности.

Механизм работы обработчика ожидания

Для начала разберем базу. Чтобы система выполняла какое-либо действие периодически (например, каждые 5 минут), нам необходимо задействовать метод ПодключитьОбработчикОжидания. Этот метод доступен только на клиенте и позволяет запускать экспортную процедуру через заданный интервал времени.

Рассмотрим, где лучше всего инициализировать этот процесс. Если уведомления должны работать глобально для всей системы, оптимальным местом будет Модуль управляемого приложения. В нем мы найдем предопределенную процедуру ПриНачалеРаботыСистемы.

Давайте проанализируем пример кода для подключения обработчика:


Процедура ПриНачалеРаботыСистемы()
    // Подключаем процедуру "ПроверитьНапоминания" с интервалом 300 секунд (5 минут)
    ПодключитьОбработчикОжидания("ПроверитьНапоминания", 300);
КонецПроцедуры

Процедура ПроверитьНапоминания() Экспорт
    // Здесь будет логика проверки данных и вызова формы
    ОткрытьФормуУведомлений();
КонецПроцедуры

Важный нюанс: процедура, которую мы подключаем, обязательно должна иметь признак Экспорт, иначе платформа не сможет ее вызвать из контекста обработчика ожидания.

Реализация через динамический список и общие формы

Простое текстовое сообщение через Сообщить() часто бывает неудобным: оно быстро теряется в панели сообщений и не позволяет пользователю перейти к объекту. Правильнее использовать Общую форму с динамическим списком. Рассмотрим по шагам, как это реализовать.

  1. Создаем новую Общую форму (например, с именем ФормаУведомлений).
  2. Добавляем на форму основной реквизит с типом ДинамическийСписок.
  3. В свойствах списка устанавливаем флаг Произвольный запрос. Это позволит нам гибко выбирать данные из различных регистров или документов.

Проанализируем пример запроса для динамического списка, который выбирает актуальные заметки для текущего пользователя:


ВЫБРАТЬ
    РегистрНапоминания.Период КАК Дата,
    РегистрНапоминания.Заметка КАК ТекстСообщения,
    РегистрНапоминания.Объект КАК СсылкаНаОбъект
ИЗ
    РегистрСведений.НапоминанияПользователей КАК РегистрНапоминания
ГДЕ
    РегистрНапоминания.Пользователь = &ТекущийПользователь
    И РегистрНапоминания.ДатаОповещения <= &ТекущаяДата

Чтобы этот список отображал корректные данные, нам нужно передать параметры в форму при ее открытии. Выясним, как это сделать правильно в процедуре ПриСозданииНаСервере нашей формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Список.Параметры.УстановитьЗначениеПараметра("ТекущийПользователь", Пользователи.ТекущийПользователь());
    Список.Параметры.УстановитьЗначениеПараметра("ТекущаяДата", ТекущаяДата());
КонецПроцедуры

Оптимизация серверных вызовов и отказ от модальности

Одной из главных ошибок начинающих разработчиков является чтение данных в цикле непосредственно на клиенте. Посмотрим на ситуацию: если мы будем считывать весь регистр сведений на стороне клиента (как в сообщении №8), это создаст колоссальную нагрузку на сеть и «подвесит» интерфейс пользователя.

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

Также крайне важно отказаться от метода ОткрытьМодально. В современных версиях платформы 1С и веб-клиенте модальные окна не поддерживаются. Вместо них используем ОткрытьФорму. Рассмотрим исправленный алгоритм вызова:


&НаКлиенте
Процедура ПроверитьНапоминания() Экспорт
    // Сначала проверяем наличие данных на сервере, чтобы не открывать пустую форму
    Если ЕстьНовыеУведомленияНаСервере() Тогда
        ПараметрыФормы = Новый Структура("АвтоматическоеОткрытие", Истина);
        ОткрытьФорму("ОбщаяФорма.ФормаУведомлений", ПараметрыФормы);
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ЕстьНовыеУведомленияНаСервере()
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ РегистрСведений.Напоминания ГДЕ ..."; // Ваш фильтр
    Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции

Использование возможностей БСП (Библиотеки стандартных подсистем)

Если ваша конфигурация построена на базе БСП, разберем более профессиональный путь. В составе библиотеки есть подсистема «Напоминания пользователя». Она уже включает в себя все необходимые механизмы:

В этом случае вам не нужно писать свой код обработчика ожидания. Достаточно включить соответствующую функциональную опцию и настроить определяемые типы для объектов, к которым вы хотите привязать напоминания. Настройку рекомендуется делать через модуль ОбщегоНазначенияКлиентПереопределяемый.ПередНачаломРаботыСистемы, как советовали эксперты в обсуждении.

Проблема «зацикливания» и каскадных окон

Проанализируем ситуацию: пользователь отошел от компьютера на час. Интервал проверки — 5 минут. Если за это время накопилось много уведомлений, по возвращении он увидит 12 открытых окон, перекрывающих друг друга. Чтобы этого избежать, придерживайтесь двух правил:

  1. Проверка на открытую форму: Перед тем как вызвать ОткрытьФорму, проверьте, не открыта ли она уже. Можно использовать глобальную переменную или поиск в открытых окнах.
  2. Управление обработчиком: В начале процедуры проверки отключайте обработчик через ОтключитьОбработчикОжидания, а в конце — подключайте заново. Это гарантирует, что новый цикл не начнется, пока не завершится текущий серверный вызов или пока пользователь не закроет окно.

Пример безопасного перезапуска обработчика:


&НаКлиенте
Процедура ПроверитьНапоминания() Экспорт
    ОтключитьОбработчикОжидания("ПроверитьНапоминания");
    
    // Логика проверки...
    
    // В конце снова включаем
    ПодключитьОбработчикОжидания("ПроверитьНапоминания", 300);
КонецПроцедуры

Использование Центра оповещений (платформа 8.3)

Начиная с версии 8.3.3, в интерфейсе «Такси» появился Центр оповещений. Это более деликатный способ уведомления пользователя. Вместо всплывающего окна, которое прерывает работу, можно использовать метод ПоказатьОповещениеПользователя.

Рассмотрим, как это выглядит в коде:


&НаКлиенте
Процедура ПоказатьБыстроеУведомление(ЗаметкаСсылка, ТекстЗаметки)
    Текст = "У вас новое напоминание!";
    Пояснение = ТекстЗаметки;
    // При клике на оповещение откроется объект
    НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(ЗаметкаСсылка);
    
    ПоказатьОповещениеПользователя(Текст, НавигационнаяСсылка, Пояснение, БиблиотекаКартинок.Информация);
КонецПроцедуры

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

← На главную