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