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