Как обработать закрытие оповещения пользователем и гарантировать прочтение сообщения

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

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

Ограничения стандартного механизма оповещений

Для начала проанализируем ситуацию с технической точки зрения. Метод ПоказатьОповещениеПользователю предназначен для асинхронного вывода кратких информационных сообщений. Рассмотрим его синтаксис:

ПоказатьОповещениеПользователю(Текст, НавигационнаяСсылка, Пояснение, Картинка, СтатусОповещения, ОбработчикОповещения)

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

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

Решение 1: Циклический показ до выполнения действия

Разберем подход, при котором система «настаивает» на выполнении действия. Если пользователь просто закрыл окно, не перейдя по ссылке, мы можем показать его снова через некоторое время. Для этого нам понадобится механизм обработчика ожидания.

Рассмотрим пример реализации:


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

Процедура ОбработатьКликПоОповещению(ДополнительныеПараметры) Экспорт
    // Здесь мы можем зафиксировать в базе или в переменной, 
    // что пользователь прочитал уведомление
    ЗафиксироватьПросмотр(ДополнительныеПараметры);
КонецПроцедуры

Чтобы это работало периодически, используем метод ПодключитьОбработчикОжидания("ПроверитьВажныеОповещения", 300) (раз в 5 минут). Если пользователь нажмет «крестик», процедура ЗафиксироватьПросмотр не выполнится, и через 5 минут оповещение появится снова. Это заставляет пользователя либо выполнить действие, либо смириться с навязчивостью системы.

Решение 2: Использование немодальных форм вместо оповещений

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

Посмотрим на алгоритм действий:

  1. Создадим небольшую форму в общей конфигурации или внутри конкретной обработки.
  2. Установим у формы свойство РежимОткрытияОкна в значение Независимый.
  3. В обработчике ПередЗакрытием добавим проверку.

Пример кода для вызова такой формы:


ПараметрыФормы = Новый Структура("ТекстСообщения, ОбъектСсылка", "Нужно утвердить заявку!", ДокументСсылка);
ОткрытьФорму("ОбщаяФорма.УведомлениеОДействии", ПараметрыФормы, , Ложь); 
// Последний параметр Ложь означает, что форма не блокирует интерфейс (немодальная)

В самой форме УведомлениеОДействии мы можем программно скрыть стандартную кнопку закрытия или выдать предупреждение:


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

Такое окно не исчезает само по себе, оно висит поверх других окон (если настроено) и требует осознанного клика по кнопке закрытия или по кнопке действия.

Решение 3: Механизм «Текущих дел» на рабочем столе

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

Разберем, как это реализовать структурно:

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

Этот метод переносит ответственность на пользователя. Объект будет «мозолить глаза» в списке дел до тех пор, пока не будет отработан. В типовых конфигурациях (БП 3.0, УТ 11) этот механизм реализован через подсистему «Текущие дела» и считается стандартом разработки.

Решение 4: Группировка уведомлений в HTML-информатор

Если пользователю приходит сразу много оповещений («скопом», как выразился автор темы), выкидывать 10 всплывающих окон — плохая практика. Рассмотрим вариант создания единого «Центра уведомлений» на базе поля HTML-документа.

Мы можем сформировать одну форму, в которой программно генерируется HTML-код со списком всех навигационных ссылок. Посмотрим, как это помогает решить проблему:

Пример формирования текста для такого поля:


ТекстHTML = "<html><body>";
ТекстHTML = ТекстHTML + "<h2>Список важных уведомлений:</h2>";
Для Каждого Стр Из ТаблицаУведомлений Цикл
    ТекстHTML = ТекстHTML + "<p><a href='" + Стр.Ссылка + "'>" + Стр.Представление + "</a></p>";
КонецЦикла;
ТекстHTML = ТекстHTML + "</body></html>";

Резюме и рекомендации

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

  1. Для информационных сообщений оставить стандартные оповещения, но смириться с тем, что их могут закрыть.
  2. Для важных, но не критичных действий использовать повторный показ через обработчик ожидания.
  3. Для критически важных уведомлений использовать независимые формы с контролем закрытия.
  4. Для системной работы с большим потоком задач внедрять панель «Текущие дела» на рабочем столе пользователя.

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

← На главную