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