Как вывести сообщение пользователю после закрытия формы в 1С:Предприятие 8.3

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

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

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

Почему сообщения исчезают и как работает механизм привязки

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

Проанализируем основные способы решения этой задачи — от простых до продвинутых.

Способ 1. Передача сообщений через параметры записи (Оптимальный для УФ)

Рассмотрим наиболее изящный метод, который подходит для большинства конфигураций на управляемых формах. Мы будем использовать обработчики формы ПослеЗаписиНаСервере и ПослеЗаписи для временного хранения очереди сообщений.

Для реализации этого метода выполним следующие шаги в модуле формы документа:

  1. В процедуре ПослеЗаписиНаСервере перехватим все сообщения, возникшие в процессе транзакции записи.
  2. Поместим их в структуру ПараметрыЗаписи, которая передается обратно на клиент.
  3. В клиентской процедуре ПослеЗаписи выведем их повторно, изменив привязку.

Посмотрим на пример кода:


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

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

Важное примечание: Установка пустого идентификатора 00000000-0000-0000-0000-000000000000 заставляет платформу вывести сообщение в «общий стек», который доступен пользователю даже после того, как текущее окно закрыто. Оно отобразится в нижней панели сообщений или в центре оповещений «Такси». Для этой задачи есть инструменты улучшения интерфейса и коммуникаций в 1С.

Способ 2. Использование реквизита формы и события ПриЗакрытии

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

Разберем алгоритм по шагам:

  1. При записи на сервере сохраняем копии сообщений в реквизит формы.
  2. В обработчике ПриЗакрытии проверяем, остались ли в списке необработанные сообщения.
  3. Если форма закрывается, выводим их «в никуда» (через пустой идентификатор).

Проанализируем пример реализации:


&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
    // Сохраняем сообщения в реквизит формы (СписокСообщений - тип СписокЗначений)
    ОбъектныеСообщения = ПолучитьСообщенияПользователю(Истина);
    Для Каждого Сообщение Из ОбъектныеСообщения Цикл
        СписокСообщений.Добавить(Сообщение);
        // Не забываем вернуть сообщение обратно в текущую сессию, если форма НЕ закроется
        Сообщение.Сообщить(); 
    КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
    Если ЗавершениеРаботы Тогда
        Возврат; // При выходе из программы сообщения не нужны
    КонецЕсли;

    ПустойУИД = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
    Для Каждого ЭлементСписка Из СписокСообщений Цикл
        ТекСообщение = ЭлементСписка.Значение;
        ТекСообщение.ИдентификаторНазначения = ПустойУИД;
        ТекСообщение.Сообщить();
    КонецЦикла;
КонецПроцедуры

Выясним причину использования СписокЗначений: это позволяет хранить сериализованные объекты СообщениеПользователю прямо в контексте формы между серверными и клиентскими вызовами.

Способ 3. ПоказатьОповещениеПользователя (Всплывающие окна)

Если информация носит ознакомительный характер, мы можем использовать механизм оповещений («всплывашек» в углу экрана) — для этого подойдёт универсальная настройка уведомлений и оповещений внутри базы. Они не привязаны к конкретной форме и живут своей жизнью до тех пор, пока не истечет время их отображения.

Однако помните: метод ПоказатьОповещениеПользователя() работает только на клиенте. Если проверка выполняется глубоко на сервере (например, в модуле объекта), нам все равно придется сначала передать текст на клиент через ПараметрыЗаписи или ДополнительныеСвойства объекта.

Пример вызова оповещения:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Если ПараметрыЗаписи.Свойство("ТекстУведомления") Тогда
        ПоказатьОповещениеПользователя(
            "Внимание!", 
            "http://ссылка_на_документ", 
            ПараметрыЗаписи.ТекстУведомления, 
            БиблиотекаКартинок.Важное);
    КонецЕсли;
КонецПроцедуры

Особенности платформы 8.3.15 и выше

Стоит отметить, что в современных версиях платформы (начиная с релиза 8.3.15) разработчики 1С значительно улучшили автоматическую доставку сообщений. В интерфейсе «Такси» многие «осиротевшие» сообщения после закрытия формы теперь автоматически попадают в Центр оповещений (иконка колокольчика в верхней панели). Тем не менее, для 100% уверенности в том, что пользователь увидит текст здесь и сейчас, программные методы перехвата через ИдентификаторНазначения остаются наиболее надежными.

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

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

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

← На главную