Строим таблицу в 1С: от конструктора отчёта до кода
Содержание
Таблицу в 1С формируют двумя путями. Если нужен отчёт, который видит пользователь, — берут систему компоновки данных (СКД): описываете запрос, перетаскиваете поля в группировки, и платформа сама рисует таблицу с итогами. Если таблица нужна внутри алгоритма — внутри обработки, при заполнении документа, перед выгрузкой в файл — её собирают кодом через объект ТаблицаЗначений или выводят результат СКД в табличный документ.
Выбор простой. Отчёт для людей — СКД: там бесплатно получаете отборы, сортировку, настройки пользователя. Промежуточные расчёты в памяти — ТаблицаЗначений: она быстрая, её удобно сворачивать и индексировать. Печатную форму или выгрузку — табличный документ. Ниже разберём каждый способ по шагам, с кодом, который можно вставить и запустить.
Система компоновки данных: из чего собирается таблица
СКД — это механизм, который по описанию «что показать» строит готовую таблицу. Разработчик задаёт схему, пользователь — настройки, платформа соединяет их и выводит результат. Писать вывод строк руками не нужно.
Схема компоновки данных состоит из нескольких частей:
- 📦 Набор данных — обычно запрос к базе. Отсюда берутся строки будущей таблицы.
- 🧮 Ресурсы — поля, по которым считаются итоги (сумма, количество, максимум).
- 📐 Поля — какие колонки доступны и как они называются для пользователя.
- 🎚️ Параметры — значения, которые подставляются в запрос (период, организация, склад).
- 🎨 Настройки — то, что видит пользователь: группировки, отборы, сортировка, условное оформление.
Главное отличие от ручного построения: группировки в настройках управляют тем, как строки сворачиваются в таблице. Поставили в структуру одну группировку Номенклатура — получите плоский список. Добавили вложенную Склад — таблица станет иерархической с подытогами.
Схему компоновки удобно держать в отчёте (объект «Отчёт») или в общем макете. Тогда её настройки правятся в режиме «1С:Предприятие» без изменения кода.
Таблица в отчёте без единой строки кода
Самый частый сценарий — собрать таблицу через конструктор. Код здесь не нужен вообще.
- Создайте объект Отчёт в конфигураторе, добавьте ему основную схему компоновки данных.
- На закладке Наборы данных добавьте набор типа «Запрос» и откройте конструктор запроса.
- Выберите таблицу-источник (например, регистр накопления
ТоварыНаСкладахили документ) и перетащите нужные поля. - Перейдите на закладку Ресурсы и отметите числовые поля, по которым нужны итоги.
- На закладке Настройки постройте структуру: перетащите поля в область «Группировки», колонки — в «Выбранные поля».
После этого отчёт уже формирует таблицу. Пользователь нажимает Сформировать — и видит строки с подытогами.
Пример запроса для набора данных, который даёт остатки по складам:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
ТоварыНаСкладахОстатки.Склад КАК Склад,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&НаДату, ) КАК ТоварыНаСкладахОстатки
Здесь Количество отмечаем ресурсом — и в таблице автоматически появится строка «Итого» и подытоги по каждой группировке.
Не выбирайте в запросе поля через *. Лишние колонки замедляют компоновку и загромождают настройки. Берите только то, что реально попадёт в таблицу.
Как построить таблицу кодом через ТаблицаЗначений
Когда таблица нужна внутри алгоритма, используют ТаблицаЗначений. Это коллекция в памяти: колонки с типами и строки со значениями.
Чтобы не путаться, какой объект брать под задачу:
| Объект | Когда брать | Что получаете |
|---|---|---|
| Отчёт на СКД | таблица для пользователя на экране | настройки, отборы, сортировка без кода |
ТаблицаЗначений | расчёты и обработка в памяти | быстрый перебор, поиск, свёртка |
ДеревоЗначений | данные с вложенностью | строки с дочерними строками |
| Табличный документ | печать и выгрузка в файл | ячейки, оформление, сохранение в Excel |
Создание с нуля и заполнение вручную:
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;
НоваяСтрока.Количество = 10;
НоваяСтрока.Сумма = 1500;
На практике таблицу чаще наполняют из запроса одной строкой — метод Выгрузить() возвращает готовую ТаблицаЗначений:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура КАК Номенклатура,
| Продажи.Количество КАК Количество,
| Продажи.Сумма КАК Сумма
|ИЗ
| РегистрНакопления.Продажи.Обороты(&Начало, &Конец, ) КАК Продажи";
Запрос.УстановитьПараметр("Начало", НачалоПериода);
Запрос.УстановитьПараметр("Конец", КонецПериода);
Таблица = Запрос.Выполнить().Выгрузить();
Чтобы пройти по строкам и обработать их, используйте цикл:
Для Каждого Строка Из Таблица Цикл
Строка.Сумма = Строка.Количество * ЦенаЗаЕдиницу;
КонецЦикла;
Если во время обхода строки нужно удалять, идите по индексам в обратную сторону — иначе собьётся нумерация:
Для Сч = Таблица.Количество() - 1 По 0 Цикл
Если Таблица[Сч].Количество = 0 Тогда
Таблица.Удалить(Сч);
КонецЕсли;
КонецЦикла;
Вывод таблицы СКД в код программно
Иногда схему компоновки нужно выполнить не в отчёте, а в коде — например, собрать таблицу для дальнейшей обработки. Схему выполняют через процессор компоновки, а результат направляют в приёмник: табличный документ или коллекцию значений.
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТабДокумент = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
СхемаКомпоновки берут из макета отчёта или общего макета, Настройки — из компоновщика настроек. Если вместо печатной формы нужна именно ТаблицаЗначений, замените приёмник на ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений — тогда на выходе получите коллекцию, а не табличный документ.
Параметры и отборы: чем ограничить таблицу
Параметры и отборы решают одну задачу — показать не всё подряд, а нужный срез. Разница в том, где они работают.
Параметры подставляются в запрос до его выполнения. Период, организация, дата остатков — это параметры. Они уменьшают выборку на уровне СУБД, то есть база возвращает меньше данных. Это всегда дешевле отбора.
Отбор применяется к уже полученным строкам. Его удобно давать пользователю: «показать только склад N», «только отрицательные остатки». В настройках СКД отбор добавляется на одноимённой закладке — поле, вид сравнения, значение.
Правило простое: то, что можно отсечь параметром в запросе, отсекайте параметром, а не отбором. Отбор по полю, которого нет в индексе, заставит платформу тянуть все строки и фильтровать их в памяти.
В коде параметр запроса задаётся методом УстановитьПараметр, а отбор у ТаблицаЗначений делается методом НайтиСтроки:
НайденныеСтроки = Таблица.НайтиСтроки(Новый Структура("Склад", ОсновнойСклад));
Группировки и итоги по строкам
Группировка — это то, что превращает плоский список в таблицу с подытогами. В СКД она настраивается перетаскиванием поля в структуру. Чем глубже вложенность, тем больше уровней итогов.
В ТаблицаЗначений аналог группировки — метод Свернуть. Он объединяет строки с одинаковыми значениями в колонках группировки и складывает колонки суммирования:
// Свернуть по номенклатуре, просуммировав количество и сумму
Таблица.Свернуть("Номенклатура", "Количество, Сумма");
Общий итог по колонке считается методом Итог:
ВсегоСумма = Таблица.Итог("Сумма");
В СКД итоги считаются по ресурсам автоматически. Важно не перепутать: ресурс — это поле, по которому платформа считает агрегат, а группировка — разрез, в котором этот агрегат показывается. Если число не попало в итоги, скорее всего, вы забыли отметить его ресурсом.
Для процентов и средних в СКД не складывайте готовые проценты — считайте выражение в ресурсе через функции Сумма() и деление. Иначе в итоговой строке получите сумму процентов вместо среднего.
Дерево значений: таблица с вложенностью
Когда строки нужно показать иерархией — группа номенклатуры, внутри неё позиции; организация, внутри неё подразделения, — плоская таблица не подходит. Для этого есть ДеревоЗначений: та же таблица, но у каждой строки может быть коллекция дочерних строк.
Создаётся дерево почти как таблица, только строки добавляются через свойство Строки:
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
Дерево.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Группа = Дерево.Строки.Добавить();
Группа.Наименование = "Материалы";
Позиция = Группа.Строки.Добавить();
Позиция.Наименование = "Бумага А4";
Позиция.Сумма = 500;
На практике дерево чаще получают из запроса с итогами. Добавьте в текст запроса секцию ИТОГИ ... ПО и выгрузите результат с обходом по группировкам:
РезультатЗапроса = Запрос.Выполнить();
Дерево = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
Платформа сама разложит строки по уровням в соответствии с группировками запроса. Каждый узел верхнего уровня будет содержать свои дочерние строки, а в колонках-ресурсах окажутся подытоги.
Дерево значений умеет отображаться в форме прямо как иерархическая таблица — через реквизит формы типа «Дерево значений». Пользователь будет сворачивать и разворачивать узлы мышью.
Обход дерева делают рекурсией: обрабатываете строку, затем вызываете ту же процедуру для её коллекции Строки. Так проходятся все уровни независимо от глубины вложенности.
Условное оформление: подсветка строк и ячеек
Условное оформление выделяет цветом строки по правилу: красным — отрицательные остатки, жёлтым — просроченные. Настраивается без кода.
В настройках СКД откройте закладку Условное оформление и добавьте элемент:
- Оформление — что меняем: цвет фона, цвет текста, шрифт, формат.
- Условие — когда применять: например,
КоличествоОстаток < 0. - Оформляемые поля — к каким колонкам применить. Оставите пустым — оформится вся строка.
Так, чтобы подсветить дефицит красным фоном, задайте условие по полю остатка меньше нуля и выберите красный цвет фона. Платформа применит оформление к каждой подходящей строке при формировании таблицы.
Несколько правил оформления выполняются по порядку сверху вниз. Если два условия противоречат друг другу, победит то, что ниже в списке. Располагайте частные правила после общих.
Что делать, если таблица формируется медленно
Таблица тормозит в двух случаях: запрос тянет слишком много данных или обработка в памяти написана неоптимально. Разбираемся по порядку.
Причины на стороне запроса и СКД:
- 🐌 Выборка всех полей через
*вместо нужных. - 🐌 Отбор применяется к результату, а не параметром в запросе.
- 🐌 Нет ограничения по периоду — таблица строит остатки за всё время.
- 🐌 Соединение с виртуальными таблицами без условий внутри скобок.
Причины на стороне кода:
- 🐌 Поиск по
ТаблицаЗначенийв цикле методомНайтиСтрокибез индекса. - 🐌 Построчное добавление в таблицу вместо
Выгрузить()из запроса.
Если по таблице часто ищут, создайте индекс один раз — поиск ускорится в разы:
Таблица.Индексы.Добавить("Номенклатура, Склад");
На больших объёмах не выгружайте всё в память разом. Если строк десятки тысяч и каждую нужно обработать, обходите выборку запроса напрямую через Выбрать(), не материализуя всю таблицу.
Отдельно стоит следить за соединениями. Левое соединение с большой таблицей без условий внутри скобок виртуальной таблицы заставляет платформу сначала собрать все строки, а уже потом их отфильтровать. Условие отбора старайтесь ставить внутри параметров виртуальной таблицы — тогда СУБД отсечёт лишнее сразу, и в таблицу попадёт меньше данных.
Частые вопросы
Чем ТаблицаЗначений отличается от табличного документа?
ТаблицаЗначений — это данные в памяти: колонки, строки, типы, по ней удобно считать и искать. Табличный документ — это визуальное представление для печати и вывода на экран, с ячейками, оформлением и объединениями. Для расчётов берут первое, для печатной формы — второе.Можно ли выгрузить сформированную таблицу в Excel?
Записать с указанием типа файла.Почему в таблице нет итоговой строки?
Как объединить строки с одинаковой номенклатурой в одну?
ТаблицаЗначений используйте метод Свернуть: первым параметром перечислите колонки группировки, вторым — колонки, которые нужно просуммировать. В отчёте то же делает группировка в структуре настроек.