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