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