В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача: при выполнении определенных действий в форме документа (например, при проведении) программно создать другой связанный объект и уведомить об этом пользователя. Сложность заключается в том, что если пользователь нажимает кнопку Провести и закрыть, форма документа мгновенно закрывается, и стандартные методы вывода сообщений, привязанные к этой форме, могут не сработать или остаться незамеченными. Разберем, как правильно организовать оповещение пользователя и какую архитектуру взаимодействия выбрать, чтобы избежать блокировок интерфейса.
Рассмотрим ситуацию: в документе ПриобретениеТоваровУслуг при выполнении определенных условий создается ЗаказКлиента. Если использовать метод ОбщегоНазначения.СообщитьПользователю, пытаясь направить сообщение в форму списка, мы столкнемся с проблемой области видимости. Метод Сообщить без привязки к конкретному идентификатору формы выводит информацию в общее окно сообщений, которое пользователь может пропустить, если форма документа уже закрылась. Привязка же сообщения к закрывающейся форме приводит к тому, что сообщение «умирает» вместе с формой.
Проанализируем ситуацию: нам нужно передать данные из одной формы (которая закрывается) в другую (которая уже открыта или будет активна — форму списка). Для этого в 1С предусмотрены механизмы глобальных оповещений и всплывающих уведомлений.
Это классический и самый надежный способ взаимодействия между формами в управляемом приложении. Метод Оповестить рассылает сигнал всем открытым формам текущего сеанса. Рассмотрим подробнее, как это реализовать.
В форме документа, в обработчике события, который срабатывает после записи (когда ссылка на новый объект уже гарантированно создана), мы вызываем клиентский метод:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
// Предположим, ссылка на созданный заказ сохранена в реквизите формы
Если ЗначениеЗаполнено(СозданныйЗаказКлиента) Тогда
СтруктураОповещения = Новый Структура;
СтруктураОповещения.Вставить("Ссылка", СозданныйЗаказКлиента);
СтруктураОповещения.Вставить("Текст", "Создан новый заказ клиента!");
Оповестить("СобытиеСозданияЗаказа", СтруктураОповещения, ЭтаФорма);
КонецЕсли;
КонецПроцедуры
Затем в форме списка документов ПриобретениеТоваровУслуг нам необходимо «поймать» это событие. Для этого используется обработчик ОбработкаОповещения:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "СобытиеСозданияЗаказа" Тогда
// Обновим список, чтобы увидеть изменения, если нужно
Элементы.Список.Обновить();
// Выведем сообщение пользователю прямо здесь
ПоказатьОповещениеПользователя("Успешно", , Параметр.Текст);
КонецЕсли;
КонецПроцедуры
Если мы хотим, чтобы в углу экрана появилось симпатичное всплывающее окно (toast-уведомление), которое не зависит от состояния форм, лучше всего использовать метод ПоказатьОповещениеПользователя. Проанализируем пример кода, который можно разместить в расширении или основной форме в процедуре ПриЗакрытии:
&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
Если НЕ ЗавершениеРаботы Тогда
// Получаем ссылку на созданный заказ из реквизита формы
ЗаказСсылка = Объект.СсылкаНаСозданныйЗаказ;
Если ЗначениеЗаполнено(ЗаказСсылка) Тогда
ТекстУведомления = Строка(ЗаказСсылка);
НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(ЗаказСсылка);
ПоказатьОповещениеПользователя(
"Создан связанный документ",
НавигационнаяСсылка,
ТекстУведомления,
БиблиотекаКартинок.ИнформационноеПисьмо
);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Выясним причину, по которой этот метод удобен: он позволяет пользователю не просто прочитать текст, но и кликнуть на уведомление, чтобы мгновенно открыть созданный Заказ клиента благодаря использованию НавигационнойСсылки.
При реализации подобной логики важно не совершить классическую ошибку новичка: создание и запись новых объектов непосредственно внутри транзакции записи основного документа (например, в модуле объекта в ПередЗаписью или ПриЗаписи). Разберем по шагам, почему это плохо:
Правильнее всего инициировать создание связанных объектов в обработчике ПослеЗаписиНаСервере в форме или использовать механизм длительных операций (фоновых заданий).
Выясним, как сделать работу системы максимально плавной. Вместо того чтобы заставлять пользователя ждать, мы можем запустить фоновое задание. Рассмотрим алгоритм:
ПослеЗаписи вызываем серверный метод, который запускает фоновое задание.Заказ клиента.Оповестить или через обработчик ожидания в форме списка уведомляет пользователя о результате.Проанализируем ситуацию: использование Библиотеки Стандартных Подсистем (БСП) значительно упрощает этот процесс. Метод ДлительныеОперации.ЗапуститьВыполнениеНаСервере позволяет выполнить создание документа в фоне, а функция ПоказатьОповещениеПользователя выведет результат, когда он будет готов, даже если пользователь уже перешел к работе с другим разделом программы.
Резюмируем: Для простого уведомления после закрытия формы используйте комбинацию Оповестить и ПоказатьОповещениеПользователя. Для сложных и тяжелых операций создания документов всегда выбирайте фоновые задания, чтобы обеспечить отзывчивость интерфейса для конечного пользователя.