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