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

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

В процессе разработки в среде 1С:Предприятие 8.3 часто возникает задача оперативного информирования ответственных лиц (например, администраторов) о действиях других пользователей. Типичный пример: педагог или учащийся изменили данные в базе, и администратор должен мгновенно получить уведомление об этом. Рассмотрим, почему стандартный подход с использованием метода ПоказатьОповещениеПользователя внутри подписки на события не работает, и разберем правильные алгоритмы реализации такой задачи.

Разбор основной ошибки: Сервер vs Клиент

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

Кроме того, даже если бы этот метод сработал, он показал бы уведомление тому пользователю, который совершает действие (педагогу), а не администратору. Нам же требуется передать сигнал в другой сеанс связи. Выясним, как это сделать правильно.

Способ 1. Использование промежуточного Регистра сведений и обработчика ожидания

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

Шаг 1. Создание регистра сведений

Создадим непериодический регистр сведений ОчередьОповещений со следующей структурой:

  1. Измерение: Идентификатор (тип УникальныйИдентификатор) — для уникальности записи.
  2. Ресурс: ТекстСообщения (тип Строка).
  3. Ресурс: ОбъектСсылка (тип ЛюбаяСсылка) — чтобы админ мог сразу открыть измененный объект.
  4. Ресурс: Просмотрено (тип Булево) — индекс для фильтрации новых записей.

Шаг 2. Написание кода в общем модуле (Сервер)

В обработчике подписки на событие (общий модуль должен иметь галку «Сервер») проанализируем ситуацию и запишем данные в регистр. Обратите внимание, что вместо привычного ЭтотОбъект в подписках используется параметр Источник.


Процедура ПриЗаписиОбъектаДляАдмина(Источник, Отказ) Экспорт
    
    // Проверяем, что запись делает не админ
    ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если ТекущийПользователь.Имя = "Администратор" Тогда
        Возврат;
    КонецЕсли;

    // Создаем запись в регистре
    НоваяЗапись = РегистрыСведений.ОчередьОповещений.СоздатьМенеджерЗаписи();
    НоваяЗапись.Идентификатор = Новый УникальныйИдентификатор();
    НоваяЗапись.ТекстСообщения = "Изменен объект: " + Строка(Источник);
    НоваяЗапись.ОбъектСсылка = Источник.Ссылка;
    НоваяЗапись.Просмотрено = Ложь;
    НоваяЗапись.Записать();
    
КонецПроцедуры

Шаг 3. Настройка клиентской части у администратора

Теперь нам нужно заставить сеанс администратора проверять этот регистр. Перейдем в Модуль управляемого приложения. Там мы подключим обработчик ожидания, который будет запускаться только у пользователя с правами администратора.


Процедура ПриНачалеРаботыСистемы()
    
    // Проверяем роль или имя пользователя
    Если ПривилегированныйРежим() Или РольДоступна("ПолныеПрава") Тогда
        // Опрашиваем базу каждые 60 секунд
        ПодключитьОбработчикОжидания("ПроверитьНовыеОповещения", 60);
    КонецЕсли;
    
КонецПроцедуры

Процедура ПроверитьНовыеОповещения() Экспорт
    // Вызываем серверную функцию для проверки регистра
    ДанныеОповещения = ВыполнитьПроверкуНаСервере();
    
    Если ДанныеОповещения <> Неопределено Тогда
        Текст = ДанныеОповещения.Текст;
        СсылкаНаОбъект = ДанныеОповещения.Ссылка;
        
        // Вот теперь клиентский метод сработает!
        ПоказатьОповещениеПользователя("Внимание!", СсылкаНаОбъект, Текст, БиблиотекаКартинок.Важное);
    КонецЕсли;
КонецПроцедуры

Способ 2. Система взаимодействия (Push-уведомления)

Если ваша платформа 8.3.10 и выше, рекомендуем использовать Систему взаимодействия. Это современный механизм, который позволяет серверу самому «толкать» уведомление клиенту без постоянных опросов базы данных. Рассмотрим подробнее этот вариант.

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


// Пример кода для отправки через Систему взаимодействия
ВыборкаПользователей = СистемаВзаимодействия.ПолучитьПользователей();
Для Каждого ПользовательСВ Из ВыборкаПользователей Цикл
    Если ПользовательСВ.Имя = "Администратор" Тогда
        НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение(ПользовательСВ.Идентификатор);
        НовоеСообщение.Текст = "Пользователь " + ИмяПользователя() + " изменил данные в форме.";
        НовоеСообщение.Записать();
    КонецЕсли;
КонецЦикла;

Администратор увидит стандартный колокольчик или всплывающее окно чата, предусмотренное платформой «1С:Предприятие».

Важные нюансы и оптимизация

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

  1. Проверка изменений: Просто нажатие кнопки «Записать» не всегда означает, что данные реально изменились. Чтобы не спамить администратора, в событии ПередЗаписью сравните текущие значения Источник и значения в базе данных (через Источник.Ссылка). Если данные идентичны, оповещение можно не создавать.
  2. Очистка логов: Если вы используете Способ 1 (регистр), не забывайте удалять старые записи. Либо делайте это сразу после показа уведомления администратору, либо настройте регламентное задание, которое раз в неделю очищает регистр ОчередьОповещений.
  3. Навигационные ссылки: Чтобы администратор мог кликнуть на уведомление и провалиться в нужный документ, используйте метод ПолучитьНавигационнуюСсылку(Источник.Ссылка).

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

← На главную