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