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