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

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

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

Почему окно сообщений закрывается вместе с формой?

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

При выполнении команды «Провести и закрыть» происходит следующая последовательность действий:

  1. Данные передаются на сервер.
  2. Выполняется транзакция записи и проведения (формируются движения, срабатывают модули регистров).
  3. Сервер возвращает результат на клиент.
  4. Платформа закрывает форму документа.
  5. Вместе с формой уничтожается и её локальный стек сообщений.

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

Решение 1: Использование метода «ПоказатьОповещениеПользователю»

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

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

Решение 2: Передача данных через «ДополнительныеСвойства» (Bridge-паттерн)

Проанализируем ситуацию: сообщение формируется в момент движений по регистру. Чтобы вывести его на клиенте после закрытия формы, нам нужно передать текст сообщения из модуля регистра обратно в форму. Для этого идеально подходит коллекция ДополнительныеСвойства.

Шаг 1. Формирование сообщения в модуле набора записей или документа.

Вместо прямого вызова Сообщить(), мы записываем текст во временную структуру:


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

Шаг 2. Перехват данных в форме документа.

Теперь нам нужно извлечь эти данные при возврате с сервера. Для этого используем обработчик ПослеЗаписиНаСервере в модуле формы.


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

Шаг 3. Вывод оповещения на клиенте.

Финальный этап — вывод информации в обработчике ПослеЗаписи. Этот метод вызывается на клиенте уже после того, как все серверные действия завершены, но до того, как форма окончательно «забудет» свой контекст.


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

Решение 3: Использование Центра оповещений (для версий 8.3.15+)

Выясним причину, по которой пользователи часто не видят сообщения. В современных версиях платформы (начиная с 8.3.15) все сообщения, отправленные через СообщениеПользователю, автоматически дублируются в «Центре оповещений» (иконка колокольчика в верхней панели интерфейса).

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

Критический взгляд на архитектуру: почему сообщения в регистрах — это плохо?

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

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

Резюме

Для реализации «неисчезающих» сообщений мы рекомендуем отказаться от прямого метода Сообщить() в пользу связки ДополнительныеСвойства + ПоказатьОповещениеПользователю(). Это обеспечит:

  1. Гарантированную доставку информации пользователю даже после закрытия формы.
  2. Современный и чистый интерфейс в стиле «Такси».
  3. Возможность добавить в оповещение гиперссылку (например, для быстрого открытия связанного отчета).

Таким образом, мы не только решаем техническую проблему закрытия окна, но и повышаем общее качество пользовательского интерфейса нашей системы.

← На главную