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