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