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

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

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

Причина исчезновения сообщений

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

Способ 1. Использование объекта СообщениеПользователю без жесткой привязки

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

Рассмотрим пример кода в модуле объекта документа:


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

Если сообщение не привязано к конкретному UUID формы, платформа 8.3 (особенно в последних релизах) постарается вывести его в «Центр оповещений» или отобразить в активном окне (например, в форме списка, которая осталась на экране после закрытия документа).

Способ 2. Использование механизма «ПоказатьОповещениеПользователю»

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

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

  1. В модуле объекта (в процедуре ОбработкаПроведения) записываем текст сообщения в ДополнительныеСвойства.
  2. В модуле формы в процедуре ПослеЗаписиНаСервере переносим это сообщение в параметры, доступные на клиенте.
  3. В клиентской процедуре ПослеЗаписи выводим уведомление.

Пример реализации в модуле объекта:


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

Пример реализации в модуле формы:


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

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

Этот метод гарантирует, что даже если форма закроется, всплывающее окно в нижнем правом углу экрана останется видимым для пользователя.

Способ 3. Использование Центра Оповещений (для БСП)

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

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

Способ 4. Определение контекста проведения через ДополнительныеСвойства

Часто возникает вопрос: как процедуре проведения понять, проводится ли документ из формы (кнопкой) или программно (например, обработкой проведения)? Это важно для решения, стоит ли вообще выводить Сообщить().

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


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

Теперь в модуле объекта мы можем проверить этот флаг:


Если ДополнительныеСвойства.Свойство("ПроведениеИзФормы") Тогда
    // Мы знаем, что пользователь нажал кнопку в форме
    // Можно использовать альтернативные методы логирования или оповещения
КонецЕсли;

Способ 5. Использование предупреждений (модальный подход)

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

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

Итоги и рекомендации

Подводя итог нашему анализу, выделим основные правила работы с сообщениями при закрытии формы:

  1. Для простых уведомлений: Используйте СообщениеПользователю без привязки к UUID формы. Платформа перенаправит его в «Центр оповещений».
  2. Для гарантированной видимости: Передавайте текст через ДополнительныеСвойства на клиент и вызывайте ПоказатьОповещениеПользователю в процедуре ПослеЗаписи.
  3. Для критических замечаний: Делайте предварительные проверки в модуле формы (на клиенте), чтобы остановить процесс закрытия и показать модальное окно (предупреждение).
  4. Для массового проведения: Всегда дублируйте важную информацию в ЖурналРегистрации, так как при программной обработке сотен документов пользователь физически не сможет прочитать сообщения в реальном времени.

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

← На главную