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