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