При разработке прикладных решений в 1С часто возникает задача: уведомить определенного пользователя о наступлении некоторого события в базе данных. Например, в регистре сведений появились неотправленные записи со статусом Выгружен = Ложь, и ответственному сотруднику необходимо напомнить о запуске обработки выгрузки.
Разберем типичные ошибки начинающих разработчиков, контекстные ограничения платформы 1С и надежные способы реализации оповещений.
Проанализируем частую ошибку: попытку вызвать методы показа сообщений прямо в коде регламентного задания или серверного модуля.
Платформа «1С:Предприятие» строго разграничивает контексты выполнения:
Сообщить, ПоказатьОповещениеПользователя, Предупреждение) в регламентном задании либо приводят к ошибке времени выполнения, либо игнорируются.СообщениеПользователю и метод ПолучитьСообщенияПользователю() работают исключительно внутри текущего сеанса. Отправить сообщение из одного сеанса напрямую в интерфейс другого сеанса через эти методы невозможно.Рассмотрим рабочие варианты реализации задачи.
Разберем по шагам наиболее прямолинейный способ: периодическая проверка условия в сеансе нужного пользователя.
Логика работы строится следующим образом:
ПодключитьОбработчикОжидания().ПоказатьОповещениеПользователя() с кликабельной ссылкой на обработку.Посмотрим на пример реализации в модуле управляемого приложения:
&НаКлиенте
Процедура ПриНачалеРаботыСистемы()
Если ЭтоОтветственныйЗаВыгрузку() Тогда
// Интервал проверки в секундах (например, раз в 10 минут)
ПодключитьОбработчикОжидания("ПроверитьНевыгруженныеДанные", 600, Ложь);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьНевыгруженныеДанные() Экспорт
Если ЕстьНевыгруженныеЗаписиНаСервере() Тогда
ТекстОповещения = "Обнаружены новые данные для выгрузки. Нажмите для запуска обработки.";
ПоказатьОповещениеПользователя("Требуется выгрузка", "e1cib/app/Обработка.ВыгрузкаДанных", ТекстОповещения);
КонецЕсли;
КонецПроцедуры
Серверная функция проверки должна быть максимально легковесной, чтобы не создавать избыточную нагрузку на СУБД:
&НаСервере
Функция ЕстьНевыгруженныеЗаписиНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| 1
|ИЗ
| РегистрСведений.ИзменениеСправ КАК Изменения
|ГДЕ
| Изменения.Выгружен = ЛОЖЬ";
Результат = Запрос.Выполнить();
Возврат НЕ Результат.Пустой();
КонецФункции
Рассмотрим современный встроенный механизм платформы 1С:Предприятие 8.3 — Систему взаимодействия. Она позволяет отправлять адресные сообщения пользователям непосредственно из серверного кода и фоновых заданий.
Разберем пример отправки уведомления из регламентного задания:
// Серверный код (выполняется в регламентном задании)
Если ЕстьНевыгруженныеЗаписиНаСервере() Тогда
// Получаем пользователя Системы взаимодействия
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("Иванов");
ИДПользователяСВ = СистемаВзаимодействия.ПолучитьИдентификатор(ПользовательИБ.УникальныйИдентификатор);
Если ИДПользователяСВ <> Неопределено Тогда
Сообщение = СистемаВзаимодействия.СоздатьСообщение();
Сообщение.Текст = "Внимание: в регистре присутствуют невыгруженные записи! Запустите обработку выгрузки.";
Сообщение.Получатели.Добавить(ИДПользователяСВ);
Сообщение.Записать();
КонецЕсли;
КонецЕсли;
При таком подходе у пользователя в правом нижнем углу интерфейса всплывает штатное системное push-уведомление, не требующее постоянных опросов базы данных на клиенте.
Если конфигурация разработана на основе Библиотеки стандартных подсистем (БСП), изобретать собственный велосипед не требуется. Рассмотрим готовые встроенные инструменты:
НапоминанияПользователей с указанием адресата и времени срабатывания. БСП автоматически выведет типовую панель напоминаний нужного сотрудника.Задача на конкретного исполнителя или роль. Пользователь увидит задачу на своем рабочем столе.При организации периодического контроля важно соблюдать правила оптимизации:
Запрос.Выполнить().Выбрать().Количество() заставляют СУБД считывать все строки. Используйте ВЫБРАТЬ ПЕРВЫЕ 1 и проверяйте условие НЕ Результат.Пустой().Выгружен является обычным реквизитом, а не измерением регистра сведений, обязательно установите для него свойство «Индексировать» в конфигураторе, чтобы поиск по условию ГДЕ Выгружен = ЛОЖЬ выполнялся по индексу, а не путем полного сканирования таблицы.