К статье
Практический материал

Разработка и Конфигурация · 12 мин

ДанныеФормыКоллекция в 1С: получение и работа с данными формы

Как получить ДанныеФормыКоллекция в 1С: преобразование таблицы формы в ТаблицуЗначений, обход строк, типичные ошибки и готовые примеры кода.

ДанныеФормыКоллекция — это объект, через который управляемая форма 1С хранит табличные данные: строки табличной части документа, строки динамического списка или таблицы значений, добавленной как реквизит формы. Напрямую обратиться к нему как к обычной ТаблицеЗначений нельзя — отсюда и возникает типовой вопрос «как получить данные из ДанныеФормыКоллекция».

Ключ к решению — понимание, что ДанныеФормыКоллекция живёт только в контексте формы. На клиенте доступен ограниченный набор методов (обход строк, поиск), а полноценная работа с данными выполняется на сервере после преобразования в прикладной объект через методы РеквизитФормыВЗначение и ДанныеФормыВЗначение.

Ниже разобраны все рабочие способы: обход коллекции на клиенте, выгрузка в таблицу значений на сервере, поиск строк, передача данных между формами, а также типичные ошибки, которые приводят к сообщениям вида «Метод объекта не обнаружен».

Что такое ДанныеФормыКоллекция и где она встречается

ДанныеФормыКоллекция — это тип данных, который платформа автоматически присваивает реквизиту управляемой формы, если тот имеет табличную структуру. Типичные случаи: реквизит формы типа ТаблицаЗначений, табличная часть объекта (при работе с ДанныеФормыСтруктура, вложенные коллекции), список в динамической форме.

Внутри коллекции находятся элементы типа ДанныеФормыЭлементКоллекции — по сути, строки с именованными полями. К каждому полю можно обратиться по имени: Строка.Номенклатура, Строка.Количество. Индексация строк тоже поддерживается: Коллекция[0] вернёт первую строку.

Важно понимать ограничение: ДанныеФормыКоллекция — это «проекция» данных на форму, а не самостоятельная таблица. У неё нет методов Скопировать(), Свернуть(), Сортировать(), которые есть у ТаблицыЗначений. Попытка вызвать их приведёт к ошибке «Метод объекта не обнаружен».

Обход строк коллекции на клиенте

Самый простой способ получить данные — перебрать строки в цикле. Это работает и на клиенте, и на сервере, не требует контекстного серверного вызова и подходит для большинства задач: подсчёт итогов, проверка заполнения, поиск нужной строки.

&НаКлиенте

Процедура ПосчитатьИтог(Команда)

ИтогСумма = 0;

Для Каждого Строка Из Объект.Товары Цикл

ИтогСумма = ИтогСумма + Строка.Сумма;

КонецЦикла;

Сообщить("Итог по таблице: " + ИтогСумма);

КонецПроцедуры

Здесь Объект.Товары — это и есть ДанныеФормыКоллекция (табличная часть документа, отображённая на форму). Обращение к полям строки идёт по именам колонок, как в обычной таблице значений.

Для поиска строк по условию используйте метод НайтиСтроки — он доступен у коллекции и на клиенте:

Отбор = Новый Структура("Номенклатура", ТекущаяНоменклатура);

НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);

Если НайденныеСтроки.Количество() > 0 Тогда

Сообщить("Найдено строк: " + НайденныеСтроки.Количество());

КонецЕсли;

Метод НайтиСтроки возвращает массив элементов коллекции, а не новую коллекцию — это важно при дальнейшей обработке: у массива нет методов таблицы, но можно обращаться к элементам по индексу и в цикле.

Преобразование в ТаблицуЗначений на сервере

Когда нужен полный набор операций — сортировка, свёртка, выгрузка колонки, передача в запрос — коллекцию преобразуют в ТаблицуЗначений. Делается это только на сервере методом РеквизитФормыВЗначение:

&НаСервере

Функция ПолучитьТаблицуТоваров()

ТаблицаТоваров = РеквизитФормыВЗначение("ТаблицаНаФорме");

// Теперь доступны все методы ТаблицыЗначений

ТаблицаТоваров.Свернуть("Номенклатура", "Количество,Сумма");

Возврат ТаблицаТоваров;

КонецФункции

Здесь "ТаблицаНаФорме" — имя реквизита формы типа ТаблицаЗначений, добавленного в дерево реквизитов в конфигураторе. После преобразования вы получаете обычную ТаблицуЗначений со всеми её методами.

Обратное преобразование — запись изменённой таблицы обратно в форму — выполняется методом ЗначениеВРеквизитФормы:

&НаСервере

Процедура ОбновитьТаблицуНаСервере()

ТаблицаТоваров = РеквизитФормыВЗначение("ТаблицаНаФорме");

// ... изменения таблицы ...

ЗначениеВРеквизитФормы(ТаблицаТоваров, "ТаблицаНаФорме");

КонецПроцедуры

Если табличные данные принадлежат объекту (например, табличная часть документа в основном реквизите формы), вместо РеквизитФормыВЗначение используют ДанныеФормыВЗначение с указанием типа:

ДокументОбъект = РеквизитФормыВЗначение("Объект");

ТаблицаТоваров = ДокументОбъект.Товары.Выгрузить();

Получение данных из динамического списка

Отдельный случай — динамический список на форме. Его данные нельзя получить через РеквизитФормыВЗначение, потому что список формируется запросом и не хранится как таблица. Работают два подхода.

Первый — обход выделенных строк через элемент формы. У элемента формы, связанного со списком, есть свойство ВыделенныеСтроки — массив идентификаторов (ключей записей или ссылок):

&НаКлиенте

Процедура ОбработатьВыделенные(Команда)

Для Каждого Строка Из Элементы.Список.ВыделенныеСтроки Цикл

Сообщить(Строка); // ссылка или ключ записи

КонецЦикла;

КонецПроцедуры

Второй — получение данных текущей строки через ТекущиеДанные элемента формы. Это объект ДанныеФормыЭлементКоллекции с полями, выведенными в список:

&НаКлиенте

Процедура ПоказатьТекущую(Команда)

ТекДанные = Элементы.Список.ТекущиеДанные;

Если ТекДанные <> Неопределено Тогда

Сообщить(ТекДанные.Наименование);

КонецЕсли;

КонецПроцедуры

Если нужно выгрузить весь динамический список целиком, придётся программно получить его компоновщик настроек, выполнить запрос на сервере и обработать результат — это уже задача уровня СКД, а не работы с коллекцией формы.

Сравнение вариантов

Обход циклом на клиенте

Подходит для итогов, проверок, поиска. Быстро, без серверного вызова. Ограничение: нет сортировки и свёртки.

РеквизитФормыВЗначение на сервере

Полноценная ТаблицаЗначений со всеми методами. Требует серверного вызова и имени реквизита формы.

НайтиСтроки с отбором

Поиск по условию без цикла, работает на клиенте. Возвращает массив, а не таблицу.

Выгрузить() у табличной части объекта

Только на сервере через объект (РеквизитФормыВЗначение("Объект")). Даёт ТаблицуЗначений из табличной части документа/справочника.

Передача данных между формами

ДанныеФормыКоллекция нельзя напрямую передать в другую форму как параметр — тип привязан к конкретной форме. Стандартный приём — преобразовать коллекцию в массив структур или в ТаблицуЗначений и передать уже её.

Вариант с массивом структур работает и на клиенте, и не требует серверного вызова:

&НаКлиенте

Процедура ПередатьВФорму(Команда)

МассивСтрок = Новый Массив;

Для Каждого Строка Из Объект.Товары Цикл

СтруктураСтроки = Новый Структура("Номенклатура,Количество,Цена");

ЗаполнитьЗначенияСвойств(СтруктураСтроки, Строка);

МассивСтрок.Добавить(СтруктураСтроки);

КонецЦикла;

ПараметрыФормы = Новый Структура("Строки", МассивСтрок);

ОткрытьФорму("Обработка.Подбор.Форма.ФормаВыбора", ПараметрыФормы, ЭтотОбъект);

КонецПроцедуры

В открываемой форме массив принимается в обработчике ПриСозданииНаСервере через Параметры.Строки и далее загружается в реквизит формы — например, через Загрузить() у таблицы значений после преобразования.

Порядок действий
  1. 1
    Определите, где находятся данные: реквизит формы, табличная часть объекта или динамический список.
  2. 2
    Для простого чтения обойдите коллекцию циклом «Для Каждого» прямо на клиенте.
  3. 3
    Для сложной обработки (сортировка, свёртка, запрос) создайте серверную процедуру и вызовите РеквизитФормыВЗначение.
  4. 4
    После изменений верните данные в форму через ЗначениеВРеквизитФормы.
  5. 5
    Проверьте результат в интерфейсе: таблица на форме должна отобразить изменения без перезаписи объекта.

Типичные ошибки и их причины

Ошибка «Метод объекта не обнаружен (Свернуть)» возникает при попытке вызвать метод ТаблицыЗначений у ДанныеФормыКоллекция. Решение — сначала преобразовать коллекцию на сервере, либо реализовать логику циклом.

Ошибка «Поле объекта не обнаружено» при обращении к полю строки означает, что в коллекции нет колонки с таким именем. Проверьте состав колонок реквизита формы в конфигураторе или имена полей табличной части — регистр букв роли не играет, а опечатка в имени — да.

Ещё одна частая проблема — попытка вызвать РеквизитФормыВЗначение в процедуре с директивой &НаКлиенте. Компилятор модуля формы это отследит, но при динамическом вызове ошибка проявится только в рантайме. Правило простое: все преобразования — в процедурах &НаСервере.

Типичные ошибки
01
Вызов Свернуть() или Скопировать() у ДанныеФормыКоллекция — методов нет, нужна серверная конвертация в ТаблицуЗначений.
02
РеквизитФормыВЗначение в клиентской процедуре — метод доступен только на сервере в контексте формы.
03
Попытка получить данные динамического списка через РеквизитФормыВЗначение — список не является реквизитом-таблицей, используйте ТекущиеДанные и ВыделенныеСтроки.
04
Передача ДанныеФормыКоллекция в другую форму напрямую — тип привязан к форме, передавайте массив структур или ТаблицуЗначений.
05
Обращение к несуществующей колонке строки — проверяйте состав колонок реквизита в конфигураторе.

Проверка результата и ограничения

После преобразования убедитесь, что таблица содержит ожидаемое число строк и колонок. Простейшая проверка — вывести Количество() и список колонок через цикл по Колонки:

Для Каждого Колонка Из ТаблицаТоваров.Колонки Цикл

Сообщить(Колонка.Имя + " : " + Колонка.ТипЗначения);

КонецЦикла;

Учитывайте ограничение по производительности: каждая пара РеквизитФормыВЗначение / ЗначениеВРеквизитФормы копирует данные целиком. На таблицах в десятки тысяч строк это заметно. Если нужно изменить лишь несколько строк, выгоднее работать с коллекцией напрямую через индексацию, без полной конвертации.

Контрольные точки

Как проверить результат

Число строк после конвертации
Норма

Совпадает с числом строк таблицы на форме

Тревожный признак

Строк меньше или больше — проверьте имя реквизита

Состав колонок
Норма

Все поля реквизита формы присутствуют

Тревожный признак

Колонки нет — проверьте дерево реквизитов в конфигураторе

Отображение после ЗначениеВРеквизитФормы
Норма

Таблица на форме обновилась без ошибок

Тревожный признак

Ошибка преобразования — типы колонок не совпадают

Итоговая логика выбора способа проста: чтение и простые проверки — циклом на клиенте, сложная обработка — конвертация на сервере, динамический список — через элементы формы, передача между формами — через массив структур.

Итог

Что важно запомнить

ДанныеФормыКоллекция — табличный реквизит формы, а не ТаблицаЗначений. На клиенте доступны обход циклом, индексация и НайтиСтроки. Полный набор методов таблицы появляется после РеквизитФормыВЗначение на сервере. Динамический список читается через ТекущиеДанные и ВыделенныеСтроки элемента формы.

Частые вопросы

Как выгрузить ДанныеФормыКоллекция в ТаблицуЗначений на клиенте?

Никак напрямую — методов выгрузки у коллекции нет. Либо соберите массив структур циклом, либо вызовите серверную процедуру с РеквизитФормыВЗначение. Учтите, что ТаблицаЗначений на тонком клиенте в управляемом приложении всё равно недоступна как тип — данные вернутся в сериализованном виде.

Чем ДанныеФормыКоллекция отличается от ДанныеФормыДерево?

ДанныеФормыКоллекция — плоская таблица с линейным списком строк. ДанныеФормыДерево хранит иерархию: у каждой строки есть метод ПолучитьЭлементы(), возвращающий вложенную коллекцию. Преобразуется дерево тем же РеквизитФормыВЗначение, но в результате получится ДеревоЗначений.

Как найти строку по значению без цикла?

Используйте метод НайтиСтроки с отбором-структурой: Коллекция.НайтиСтроки(Новый Структура("Колонка", Значение)). Метод вернёт массив подходящих строк и работает как на клиенте, так и на сервере.

Почему РеквизитФормыВЗначение выдаёт ошибку «Реквизит не найден»?

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

Можно ли изменить строку коллекции напрямую?

Да. Обратитесь к строке по индексу или через НайтиСтроки и присвойте значения полям: Коллекция[0].Цена = 100. Изменения сразу отразятся на форме без дополнительных вызовов.

Как получить данные табличной части документа из его формы?

На клиенте обходите Объект.ИмяТабличнойЧасти циклом. На сервере — получите объект через РеквизитФормыВЗначение("Объект") и вызовите Выгрузить() у табличной части: вы получите полноценную ТаблицуЗначений.