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

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

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

Метод 1. Использование функции ПоказатьОповещениеПользователя

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

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


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

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

Метод 2. Механизм глобальных оповещений (метод Оповестить)

Если нам нужно, чтобы сообщение гарантированно было привязано к интерфейсу (например, вывелось в окне формы списка, из которой был открыт документ), мы можем использовать метод Оповестить. Это архитектурно более правильный подход для управляемого приложения, особенно если в системе реализовано программное изменение форм через общий модуль.

Разберем этот механизм по шагам:

  1. В форме документа: В процедуре ПослеЗаписи мы отправляем оповещение всей системе (подобно тому, как работают подключаемые команды БСП).
  2. В форме списка (или другой «живучей» форме): Мы ловим это оповещение в обработчике ОбработкаОповещения и выводим сообщение уже там. Кстати, доработка динамических списков часто требует именно такого взаимодействия между окнами.

Пример кода в форме закрываемого документа:


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

Теперь посмотрим на пример кода в форме списка, которая остается открытой после закрытия формы документа:


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

Этот способ является наиболее надежным, так как сообщение привязывается к активной форме владельца или форме списка, которая не закрывается.

Метод 3. Использование СообщениеПользователю с привязкой к данным

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

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


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

Метод 4. Вывод модального (асинхронного) предупреждения

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

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


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Текст сообщения
    Текст = "Внимание! На основании этого документа был автоматически сформирован новый документ." 
          + Символы.ПС + "Проверьте правильность заполнения реквизитов.";
    
    // Описание оповещения при закрытии самого предупреждения (если нужно)
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЭтаФорма);
    
    ПоказатьПредупреждение(Оповещение, Текст, 60, "Важное уведомление");
КонецПроцедуры

&НаКлиенте
Процедура ПослеЗакрытияПредупреждения(ДополнительныеПараметры) Экспорт
    // Здесь можно выполнить действия после того, как пользователь нажал ОК
КонецПроцедуры

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

Метод 5. Использование ОписанияОповещенияЗакрытия

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

В вызывающей форме (например, в обработке):


&НаКлиенте
Процедура ОткрытьДокумент()
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияДокумента", ЭтаФорма);
    ОткрытьФорму("Документ.ПриходнаяНакладная.ФормаОбъекта", , , , , , Оповещение);
КонецПроцедуры

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

В форме самого документа при закрытии:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Если нужно передать сигнал о создании чего-то нового
    Если ДокументБылСоздан Тогда
        ОповеститьОЗавершении("ДокументСоздан");
    КонецЕсли;
КонецПроцедуры

Подведем итоги

Мы проанализировали несколько способов решения задачи. Выбор конкретного метода зависит от требований к интерфейсу:

  1. Для ненавязчивых уведомлений лучше всего подходит ПоказатьОповещениеПользователя.
  2. Для гарантированного отображения в контексте других открытых окон используйте механизм Оповестить и обработку в форме-владельце.
  3. Для критически важных уведомлений используйте ПоказатьПредупреждение.
  4. Если сообщение должно быть привязано к данным, используйте СообщениеПользователю с установленным свойством КлючДанных.

Использование этих подходов позволит вам создавать профессиональный и понятный интерфейс, где пользователь никогда не пропустит важную системную информацию.

← На главную