Почему табличная часть обработки не отображается в другой управляемой форме 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие 8.3 на управляемых формах разработчики часто сталкиваются с ситуацией: в основной форме внешней или встроенной обработки заполняется табличная часть, затем программно открывается дополнительная форма этой же обработки, однако табличная часть на ней оказывается абсолютно пустой. Разберем подробно, почему так происходит и какими способами можно правильно передать данные между формами.

Выясним причину: изоляция контекстов управляемых форм

Главная причина такого поведения заключается в архитектуре клиент-серверного взаимодействия и специфике работы необъектных сущностей (обработок и отчетов):

  1. Отсутствие постоянной ссылки в базе данных. В отличие от документов или справочников, экземпляр обработки существует только в оперативной памяти во время выполнения. Платформа не может автоматически сопоставить две разные формы по ссылке или ключу объекта.
  2. Изолированность контекстов. При вызове метода ОткрытьФорму для формы обработки платформа создает на сервере совершенно новый, независимый экземпляр ОбработкаОбъект со значениями по умолчанию.
  3. Работа с реквизитами формы, а не с объектом базы. На клиенте реквизит Объект представляет собой коллекцию данных формы (ДанныеФормыСтруктура), а его табличные части — ДанныеФормыКоллекция. Изменения, внесенные на одной форме, никак не влияют на другие открытые формы и не синхронизируются автоматически.

Для прямого заполнения данных на клиенте в рамках одной формы не обязательно каждый раз вызывать РеквизитФормыВЗначение и ЗначениеВРеквизитФормы. Посмотрим на простой пример прямой работы с данными формы:


СтрокаТЗ = Объект.Товары.Добавить();
СтрокаТЗ.Номенклатура = НоменклатураТекущий;
СтрокаТЗ.Количество   = КоличествоЗабраноТекущее;

Однако если эти данные требуется передать в другую форму, необходимо использовать один из штатных механизмов взаимодействия управляемых форм.

Способ 1. Передача данных через параметры формы и метод ЗначениеВДанныеФормы

Рассмотрим наиболее быстрый и лаконичный вариант: передать таблицу значений напрямую через структуру параметров при открытии второй формы, а затем на сервере загрузить переданные строки в реквизит формы.

В исходной форме сформируем структуру параметров и откроем подчиненную форму:


&НаСервере
Функция ПолучитьТаблицуТоваров()
    Возврат РеквизитФормыВЗначение("Объект.Товары");
КонецФункции

&НаКлиенте
Процедура ОткрытьВторуюФорму()
    ТаблицаДляПередачи = ПолучитьТаблицуТоваров();
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("ТаблицаТовары", ТаблицаДляПередачи);
    
    ОткрытьФорму("Обработка.МояОбработка.Форма.ВтораяФорма", ПараметрыОткрытия, ЭтотОбъект);
КонецПроцедуры

Во второй форме в обработчике ПриСозданииНаСервере выполним прием данных:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("ТаблицаТовары") И Параметры.ТаблицаТовары <> Неопределено Тогда
        ЗначениеВДанныеФормы(Параметры.ТаблицаТовары, Объект.Товары);
    КонецЕсли;
КонецПроцедуры

Способ 2. Передача через временное хранилище

Если объем передаваемой таблицы велик или требуется передать сложную структуру данных, оптимально использовать временное хранилище. Важно привязать адрес хранилища к уникальному идентификатору формы, чтобы платформа корректно управляла временем жизни этих данных.

В основной форме выгружаем данные во временное хранилище:


&НаСервере
Функция ПоместитьТаблицуВХранилище()
    ТаблицаТовары = РеквизитФормыВЗначение("Объект.Товары");
    Возврат ПоместитьВоВременноеХранилище(ТаблицаТовары, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ОткрытьФормуЧерезХранилище()
    АдресХранилища = ПоместитьТаблицуВХранилище();
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("АдресТоваровВХранилище", АдресХранилища);
    
    ОткрытьФорму("Обработка.МояОбработка.Форма.ВтораяФорма", ПараметрыОткрытия, ЭтотОбъект);
КонецПроцедуры

В подчиненной форме извлекаем таблицу по переданному адресу:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("АдресТоваровВХранилище") Тогда
        ТаблицаИзХранилища = ПолучитьИзВременногоХранилища(Параметры.АдресТоваровВХранилище);
        Если ТипЗнч(ТаблицаИзХранилища) = Тип("ТаблицаЗначений") Тогда
            ЗначениеВДанныеФормы(ТаблицаИзХранилища, Объект.Товары);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Способ 3. Возврат измененных данных обратно в основную форму

Если во второй форме пользователь редактирует строки и результат нужно вернуть назад, используем механизм оповещений через ОписаниеОповещения или событие Оповестить.

Посмотрим на пример работы с описанием оповещения:


&НаКлиенте
Процедура ОткрытьФормуСВозвратомДанных()
    Оповещение = Новый ОписаниеОповещения("ОбработатьЗакрытиеВторойФормы", ЭтотОбъект);
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("ТаблицаТовары", ПолучитьТаблицуТоваров());
    
    ОткрытьФорму("Обработка.МояОбработка.Форма.ВтораяФорма", ПараметрыОткрытия, ЭтотОбъект, , , , Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьЗакрытиеВторойФормы(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    Если РезультатЗакрытия <> Неопределено Тогда
        // Загружаем обновленные данные в форму
        ЗагрузитьТаблицуНаСервере(РезультатЗакрытия);
    КонецЕсли;
КонецПроцедуры

Способ 4. Пересмотр архитектуры: объединение интерфейса в одной форме

Проанализируем задачу с точки зрения интерфейсных решений. Создание нескольких форм для одной обработки часто является избыточным. Если цель заключается в разделении этапов работы с данными, гораздо эффективнее использовать элементы интерфейса на одной форме:

  1. Группа «Страницы» (Панель с закладками или шагами). Размещение шагов мастера на разных вкладках одной формы позволяет избежать накладных расходов на передачу данных между серверными контекстами.
  2. Динамическое управление видимостью. Скрытие и отображение нужных групп элементов через свойство Видимость элементов формы позволяет работать с единым реквизитом Объект.Товары на протяжении всего сценария.
← На главную