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