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

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

1С управляемая форма: как вывести таблицу значений

Как вывести таблицу значений на управляемую форму 1С: реквизит формы, динамический список, дерево значений, код, примеры и типичные ошибки разработчика.

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

Выбор способа зависит от источника данных. Если таблица строится программно (результат обработки, расчёт, произвольный набор строк) — подходит реквизит формы типа «ТаблицаЗначений». Если данные иерархические — нужен «ДеревоЗначений». Если требуется отображать сущности базы данных с отбором и сортировкой — правильнее динамический список. Ниже разобраны все варианты с кодом, настройкой элементов формы и типичными ошибками.

Почему таблицу значений нельзя вывести напрямую

В управляемых формах платформа разделяет представление и данные. Элемент формы «Таблица» отображает не сам объект ТаблицаЗначений, а реквизит формы соответствующего типа. Это связано с клиент-серверной архитектурой: данные формы сериализуются и передаются между клиентом и сервером, а произвольный объект вроде результата запроса таким образом передать нельзя.

Из этого следуют два практических правила. Первое: перед выводом таблицы её нужно описать как реквизит формы — либо в конфигураторе на закладке «Реквизиты», либо программно через метод ИзменитьРеквизиты(). Второе: если таблица значений получена в коде (например, Выгрузить() из результата запроса), её нужно поместить в реквизит формы, а не пытаться присвоить элементу.

Вывод таблицы через реквизит формы в конфигураторе

Самый надёжный способ — описать структуру таблицы заранее в конфигураторе. Откройте форму, перейдите на закладку «Реквизиты» и добавьте реквизит, например «Товары», с типом «ТаблицаЗначений». Затем раскройте его и добавьте подчинённые реквизиты — это будут колонки: «Номенклатура» (СправочникСсылка.Номенклатура), «Количество» (Число), «Цена» (Число) и так далее.

После этого перетащите реквизит «Товары» из панели реквизитов в дерево элементов формы. Платформа автоматически создаст элемент «Таблица» с колонками. При необходимости настройте свойства: ПутьКДанным уже будет заполнен, можно включить или отключить командную панель, строку поиска, подвал.

Заполнение таблицы выполняется в коде модуля формы, обычно в обработчике ПриСозданииНаСервере или по команде:

&НаСервере

Процедура ЗаполнитьТовары()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура,

| Количество,

| Цена

|ИЗ

| РегистрСведений.ЦеныНоменклатуры";

Товары.Загрузить(Запрос.Выполнить().Выгрузить());

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

Метод Загрузить() очищает реквизит и заполняет его строками из переданной таблицы значений. Колонки сопоставляются по именам, поэтому имена полей запроса должны совпадать с именами подчинённых реквизитов. Лишние колонки в источнике будут проигнорированы, отсутствующие — останутся пустыми.

Порядок действий
  1. 1
    Откройте форму в конфигураторе, закладка «Реквизиты»
  2. 2
    Добавьте реквизит типа «ТаблицаЗначений» и подчинённые реквизиты-колонки
  3. 3
    Перетащите реквизит в дерево элементов формы — появится таблица
  4. 4
    В коде формы заполните реквизит методом Загрузить() или Добавить()/ЗаполнитьЗначенияСвойств()
  5. 5
    Откройте форму в режиме Предприятие и проверьте отображение строк и колонок

Программное создание реквизита и элемента таблицы

Если структура таблицы заранее неизвестна (например, колонки формируются динамически по настройкам пользователя), реквизиты и элементы создаются кодом в обработчике ПриСозданииНаСервере. Сначала формируется массив добавляемых реквизитов, затем вызывается ИзменитьРеквизиты(), после чего программно создаётся элемент формы.

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Добавляемые = Новый Массив;

Добавляемые.Добавить(Новый РеквизитФормы("ДанныеТаблицы",

Новый ОписаниеТипов("ТаблицаЗначений")));

Добавляемые.Добавить(Новый РеквизитФормы("Наименование",

Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)),

"ДанныеТаблицы"));

Добавляемые.Добавить(Новый РеквизитФормы("Сумма",

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)),

"ДанныеТаблицы"));

ИзменитьРеквизиты(Добавляемые);

ТаблицаЭлемент = Элементы.Добавить("ДанныеТаблицы", Тип("ТаблицаФормы"));

ТаблицаЭлемент.ПутьКДанным = "ДанныеТаблицы";

Колонка = Элементы.Добавить("ДанныеТаблицыНаименование", Тип("ПолеФормы"), ТаблицаЭлемент);

Колонка.Вид = ВидПоляФормы.ПолеВвода;

Колонка.ПутьКДанным = "ДанныеТаблицы.Наименование";

Колонка = Элементы.Добавить("ДанныеТаблицыСумма", Тип("ПолеФормы"), ТаблицаЭлемент);

Колонка.Вид = ВидПоляФормы.ПолеВвода;

Колонка.ПутьКДанным = "ДанныеТаблицы.Сумма";

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

Обратите внимание: реквизиты колонок создаются с указанием пути — имени родительского реквизита-таблицы. Элементы колонок добавляются в контейнер таблицы, а их ПутьКДанным строится как «ИмяТаблицы.ИмяКолонки». Пропуск любого из этих шагов приводит к пустой форме или ошибке «Реквизит не найден».

Заполнение реквизита из существующей таблицы значений

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

&НаСервере

Процедура ПеренестиВФорму(ТаблицаИсточник)

// Вариант 1: структуры совпадают

ДанныеТаблицы.Загрузить(ТаблицаИсточник);

// Вариант 2: универсальное преобразование

ЗначениеВДанныеФормы(ТаблицаИсточник, ДанныеТаблицы);

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

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

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

Альтернативы: динамический список и дерево значений

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

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

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

Реквизит «ТаблицаЗначений»

Произвольные данные, расчёты, временные наборы строк. Полный контроль, но вся таблица хранится в данных формы — на больших объёмах это замедляет работу.

Динамический список

Данные из таблиц базы с отбором и сортировкой. Быстро на больших объёмах, но источником может быть только запрос, а не произвольная таблица.

Реквизит «ДеревоЗначений»

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

Табличный документ

Только просмотр и печать результата, без интерактивного редактирования на форме.

Типичные ошибки и как их избежать

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

Вторая группа ошибок связана с контекстом выполнения. Методы ИзменитьРеквизиты() и ЗначениеВДанныеФормы() доступны только на сервере. Попытка вызвать их в клиентской процедуре даст ошибку компиляции или выполнения. Если заполнение инициируется пользователем, делайте клиентский обработчик-обёртку, который вызывает серверную процедуру.

Третья ошибка — попытка вывести на форму очень большую таблицу. Данные формы сериализуются при каждом серверном вызове, и таблица на десятки тысяч строк заметно тормозит открытие и работу формы. В таких случаях переходите на динамический список или ограничивайте выборку отбором.

Типичные ошибки
01
Присваивание таблицы значений элементу формы вместо реквизита — элемент не отображает данные
02
Несовпадение имён колонок источника и подчинённых реквизитов — Загрузить() молча оставляет колонки пустыми
03
Вызов ИзменитьРеквизиты() после отображения формы — ошибка выполнения
04
Вывод десятков тысяч строк в реквизит формы — форма открывается медленно и «подвисает» при серверных вызовах
05
Заполнение таблицы в клиентской процедуре при формировании данных на сервере без возврата результата

Проверка результата

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

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

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

Отображение строк
Норма

В таблице видны все ожидаемые строки с заполненными колонками

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

Таблица пустая или часть колонок пуста при наличии данных в источнике

Типы данных
Норма

Даты, числа и ссылки отображаются корректно и доступны для ввода

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

Все значения показаны как строки или поля недоступны для редактирования

Скорость работы
Норма

Форма открывается быстро, серверные вызовы не тормозят

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

Заметные паузы при открытии и каждом обращении к серверу — признак слишком большой таблицы

Итог

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

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

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

Можно ли вывести таблицу значений без создания реквизита формы?

Нет. Элемент «Таблица» управляемой формы обязан иметь источник данных — реквизит формы или динамический список. Если структура заранее неизвестна, реквизит создаётся программно через ИзменитьРеквизиты() в ПриСозданииНаСервере.

Как вывести таблицу значений, полученную в общем модуле?

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

Почему метод Загрузить() не заполняет часть колонок?

Загрузить() сопоставляет колонки по именам. Проверьте, что имена колонок таблицы-источника в точности совпадают с именами подчинённых реквизитов формы, включая регистр букв. Несовпадающие колонки пропускаются без сообщения об ошибке.

Как сделать таблицу на форме доступной только для просмотра?

Установите у элемента таблицы свойство ТолькоПросмотр в Истина или отключите свойства ИзменятьСоставСтрок и ИзменятьПорядокСтрок. Дополнительно можно скрыть командную панель таблицы, чтобы убрать кнопки добавления и удаления.

Что выбрать для вывода результата запроса: таблицу значений или динамический список?

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

Как обновить таблицу на форме по кнопке?

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