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