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