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