В процессе автоматизации бизнес-процессов часто возникает задача оперативного информирования пользователей о важных событиях в системе. Например, менеджеры должны мгновенно узнавать о появлении новых необработанных заказов, незаполненных рекламаций или критических изменений в документах. Идеальное решение — появление аккуратного всплывающего окна в правом нижнем углу экрана, которое не блокирует работу пользователя, но привлекает его внимание.
В этой статье мы подробно разберем, как реализовать такую систему оповещений. Выясним, почему стандартные внешние обработки могут выдавать ошибки при работе в фоновом режиме, изучим классическую схему с использованием обработчиков ожидания и рассмотрим современные оптимизированные подходы, которые не перегружают сервер базы данных.
---
Часто разработчики пытаются решить задачу «малой кровью», создавая внешнюю обработку в механизме Дополнительные отчеты и обработки библиотеки стандартных подсистем (БСП). Однако при попытке ее запуска система выдает ошибку:
{ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(2354)}: Метод объекта не обнаружен (ВыполнитьКоманду)
Давайте проанализируем причину этой ошибки. Когда внешняя обработка регистрируется в справочнике БСП с видом команды Вызов клиентского метода, БСП жестко ожидает, что в модуле формы этой обработки будет объявлена стандартная экспортная процедура-обработчик.
Если разработчик называет процедуру по-своему (например, ПоказатьОповещение), БСП просто не находит точку входа в алгоритм. Чтобы исправить эту ошибку во внешней обработке, в модуле основной формы обязательно нужно объявить следующую процедуру:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
// Здесь должна быть логика запуска вашей обработки
ПоказатьОповещениеНовыхЗаказов();
КонецПроцедуры
Важное ограничение: Даже при успешном исправлении этой ошибки внешняя обработка не сможет выполнять проверку в фоновом режиме, если пользователь ее закроет. Как только форма внешней обработки закрывается, все связанные с ней обработчики ожидания (подключенные через ПодключитьОбработчикОжидания) немедленно прекращают работу. Заставлять пользователя держать окно обработки постоянно открытым — неэффективно и неудобно. Поэтому для реализации полноценного фонового оповещения необходимо вносить изменения в конфигурацию или использовать механизмы расширений.
---
Рассмотрим надежный и проверенный способ создания периодических оповещений, который работает на уровне всей системы при запуске сеанса пользователя. Данный метод состоит из четырех последовательных шагов.
Создадим общий модуль с именем МойМодульВызовСервера. В свойствах модуля обязательно взведем флаги Сервер и Вызов сервера. Этот модуль будет отвечать за непосредственное обращение к базе данных и проверку условий.
Функция УведомлениеОбОбработкеНеобходимо() Экспорт
// Проверим, есть ли в системе новые согласованные предзаказы
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Первые 1
| ПредварительныйЗаказ.Ссылка КАК Ссылка
|ИЗ
| Документ.ПредварительныйЗаказ КАК ПредварительныйЗаказ
|ГДЕ
| ПредварительныйЗаказ.СтатусЗаказа = &Статус";
Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыЗаказовКлиентов.Согласован);
РезультатЗапроса = Запрос.Выполнить();
// Если результат не пустой, значит есть документы, требующие внимания
Возврат НЕ РезультатЗапроса.Пустой();
КонецФункции
Создадим общий модуль МойМодульКлиентГлобальный. В его свойствах установим флаги Клиент (управляемое приложение) и Глобальный. Этот модуль необходим, поскольку обработчики ожидания могут вызывать процедуры только из глобальных общих модулей.
Процедура МояПроверкаНовыхЗаказовСУведомлением() Экспорт
// Вызываем серверную функцию проверки
Если МойМодульВызовСервера.УведомлениеОбОбработкеНеобходимо() Тогда
// Выводим стандартное системное оповещение в правом нижнем углу
ПоказатьОповещениеПользователя(
"Внимание!",
"ПолучитьНавигационнуюСсылкаНаИнформационнуюПанель()", // Опционально: ссылка для перехода
"Имеются необработанные предзаказы!",
БиблиотекаКартинок.Информация
);
КонецЕсли;
КонецПроцедуры
Создадим общий модуль МойМодульКлиент с флагом Клиент (управляемое приложение) (флаг Глобальный должен быть выключен). Здесь мы опишем процедуру инициализации нашего таймера.
Процедура ПодключитьПроверкиНаКлиентеПоРасписанию() Экспорт
// Подключаем глобальную процедуру опроса каждые 300 секунд (5 минут)
// Третий параметр "Ложь" указывает, что обработчик будет выполняться многократно
ПодключитьОбработчикОжидания("МояПроверкаНовыхЗаказовСУведомлением", 300, Ложь);
КонецПроцедуры
Чтобы оповещения запускались сразу после авторизации пользователя, нам нужно привязать запуск к началу работы системы. Если ваша конфигурация построена на БСП, то лучшее место для этого — общий модуль ОбщегоНазначенияКлиентПереопределяемый, процедура ПослеНачалаРаботыСистемы.
Добавим вызов нашего модуля в самый конец процедуры:
Процедура ПослеНачалаРаботыСистемы() Экспорт
// ... Стандартный код БСП ...
// Интеграция нашего механизма уведомлений
МойМодульКлиент.ПодключитьПроверкиНаКлиентеПоРасписанию();
КонецПроцедуры
---
Изменение типовой конфигурации напрямую усложняет последующие обновления базы данных. Современный стандарт разработки в среде «1С:Предприятие 8.3» диктует использование **расширений конфигурации**. Это позволяет внедрить систему оповещений, сохранив основную конфигурацию на полной поддержке.
Давайте разберем, как перенести описанную выше логику в расширение:
ОбщегоНазначенияКлиентПереопределяемый.Мой_МодульУведомленийКлиент.ОбщегоНазначенияКлиентПереопределяемый создайте процедуру, расширяющую стандартную с помощью аннотации &После:
&После("ПослеНачалаРаботыСистемы")
Процедура Мой_ПослеНачалаРаботыСистемы()
// Подключаем таймер из нашего расширения
ПодключитьОбработчикОжидания("МояГлобальнаяПроверкаУведомлений", 300, Ложь);
КонецПроцедуры
Таким образом, основная конфигурация остается нетронутой, а вся логика опроса изолирована внутри расширения.
---
Описанный выше классический метод с обработчиком ожидания имеет один существенный недостаток, называемый polling (опрос). Представьте ситуацию: в вашей базе одновременно работают 100 или 200 пользователей. Каждые 5 минут клиентское приложение каждого пользователя отправляет на сервер тяжелый поисковый запрос к таблице документов. Это создает огромную паразитную нагрузку на СУБД.
Чтобы оптимизировать этот процесс и гарантировать высокую скорость работы системы, применим двухэтапную архитектуру с буферным регистром сведений.
Схема оптимизации:
ОчередьУведомлений со следующей структурой:
Пользователь (Тип: СправочникСсылка.Пользователи)ЕстьНовыеДокументы (Тип: Булево)Истина в регистр ОчередьУведомлений.
Функция ПроверитьНаличиеЗаписейВБуфере(ТекущийПользователь) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОчередьУведомлений.ЕстьНовыеДокументы КАК ЕстьНовые
|ИЗ
| РегистрСведений.ОчередьУведомлений КАК ОчередьУведомлений
|ГДЕ
| ОчередьУведомлений.Пользователь = &Пользователь";
Запрос.УстановитьПараметр("Пользователь", ТекущийПользователь);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
// Очищаем буфер после прочтения, чтобы уведомление не дублировалось
НачатьТранзакцию();
МенеджерЗаписи = РегистрыСведений.ОчередьУведомлений.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Пользователь = ТекущийПользователь;
МенеджерЗаписи.Удалить();
ЗафиксироватьТранзакцию();
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Эта архитектура снижает нагрузку на СУБД в десятки раз, так как чтение по первичному ключу из маленького регистра сведений происходит практически мгновенно.
---
Если в вашей конфигурации уже внедрена Библиотека Стандартных Подсистем, вам не обязательно создавать новые общие модули и регистры. БСП содержит отличный встроенный механизм Напоминания пользователя.
Вы можете программно создавать записи в регистре сведений НапоминанияПользователя при проведении или изменении статуса предварительного заказа. Платформа 1С под капотом сама регулярно опрашивает этот регистр для текущего активного пользователя и выводит штатное удобное диалоговое окно со списком напоминаний, откуда пользователь в один клик может перейти непосредственно в сам документ.
Пример программного создания напоминания для конкретного пользователя:
ЗаписьНапоминания = РегистрыСведений.НапоминанияПользователя.СоздатьМенеджерЗаписи();
ЗаписьНапоминания.Пользователь = ОтветственныйМенеджер;
ЗаписьНапоминания.ВремяСобытия = ТекущаяДата();
ЗаписьНапоминания.Источник = СсылкаНаПредзаказ;
ЗаписьНапоминания.СпособУстановкиВремени = Перечисления.СпособыУстановкиВремениНапоминания.ВРядомСобытием;
ЗаписьНапоминания.Описание = "Поступил новый предварительный заказ!";
ЗаписьНапоминания.Записать();
---
Самым технологичным и производительным подходом в платформе 1С:Предприятие 8.3 является использование Системы взаимодействия.
В отличие от таймеров, которые постоянно "дергают" сервер (механизм Pull), Система взаимодействия работает по протоколу WebSockets (механизм Push). Как только на сервере происходит событие (например, менеджер согласовал предзаказ), сервер отправляет сообщение в Систему взаимодействия. Платформа мгновенно и без задержек доставляет push-уведомление нужному пользователю.
Это полностью исключает паразитную нагрузку на базу данных и обеспечивает мгновенную доставку информации адресатам.