Система компоновки данных изнутри: от схемы и запроса до готового отчёта
Содержание
СКД (система компоновки данных) в 1С работает как конвейер из четырёх звеньев: схема описывает, откуда брать данные, настройки — что показать пользователю, компоновщик макета склеивает их в исполняемый макет, а процессор компоновки выполняет запрос и отдаёт результат процессору вывода. Разработчик пишет запрос один раз, а пользователь сам меняет отборы, группировки и колонки без правки кода.
Именно поэтому почти все отчёты типовых конфигураций на платформе 8.3 построены на системе компоновки. Старый путь «запрос + табличный макет + код вывода» быстрее для одной печатной формы, но любой новый срез в нём — это доработка. В СКД новый срез — это вариант отчёта.
Что такое СКД и какую задачу она решает
Система компоновки данных — механизм платформы 1С:Предприятие 8, который разделяет получение данных и их представление. До появления СКД каждую группировку и каждый итог программист выводил вручную, обходя выборку запроса.
Что даёт СКД на практике:
- 📊 пользователь сам строит отчёт: группирует, сортирует, ставит отборы, добавляет поля;
- 🔁 одна схема — много вариантов отчёта (по контрагентам, по номенклатуре, по месяцам);
- 🔎 расшифровка: двойной клик по сумме открывает детализацию или документ;
- 🧩 вывод не только в табличный документ, но и в таблицу значений или дерево;
- ⚙️ запрос оптимизируется под текущие настройки: лишние поля и таблицы не выбираются.
Цена удобства — порог входа. Схема живёт в конструкторе с десятком вкладок, и ошибка в одном флажке ломает итоги без всякого сообщения.
Из чего состоит система компоновки данных
Объекты СКД удобно разложить по ролям. Их имена совпадают с типами встроенного языка, это пригодится, когда дойдёт до кода.
| Звено | Тип во встроенном языке | Что делает |
|---|---|---|
| Схема | СхемаКомпоновкиДанных | Наборы данных, связи, вычисляемые поля, ресурсы, параметры, макеты оформления |
| Настройки | НастройкиКомпоновкиДанных | Структура отчёта: группировки, выбранные поля, отборы, сортировки, условное оформление |
| Компоновщик настроек | КомпоновщикНастроекКомпоновкиДанных | Хранит настройки и пользовательские изменения, связывает их с формой отчёта |
| Компоновщик макета | КомпоновщикМакетаКомпоновкиДанных | Из схемы и настроек собирает макет компоновки — готовый план выполнения |
| Макет компоновки | МакетКомпоновкиДанных | Итоговые тексты запросов, описание группировок и областей вывода |
| Процессор компоновки | ПроцессорКомпоновкиДанных | Выполняет запросы, считает итоги, выдаёт элементы результата |
| Процессор вывода | ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент | Превращает элементы результата в табличный документ |
Схема хранится в макете отчёта с типом «Схема компоновки данных». Если у отчёта задана основная схема, форма отчёта уже умеет её выполнять — кнопка Сформировать работает без единой строки кода.
Вкладки конструктора схемы
Конструктор открывается двойным кликом по макету. Вкладки повторяют состав схемы:
- Наборы данных — источники: запрос, объект (внешняя таблица значений) или объединение нескольких наборов.
- Связи наборов данных — как соединять наборы между собой.
- Вычисляемые поля — поля, которых нет в запросе, со своим выражением.
- Ресурсы — поля, по которым считаются итоги.
- Параметры — значения, которые передаются в запрос и выражения.
- Макеты — своё оформление отдельных областей вывода.
- Вложенные схемы — схема внутри схемы.
- Настройки — структура варианта отчёта.
Как СКД выполняет запрос к базе данных
Главное отличие СКД от обычного запроса — текст в наборе данных не исполняется как есть. Компоновщик макета читает его, смотрит на настройки и собирает новый текст.
Что происходит при нажатии Сформировать:
- Компоновщик настроек отдаёт текущие настройки с учётом пользовательских изменений.
- Компоновщик макета анализирует запрос: какие поля реально нужны для выбранных колонок, группировок, отборов и сортировок.
- Неиспользуемые поля выбрасываются. Таблицы, которые не помечены как обязательные и из которых ничего не выбрано, тоже уходят из соединений.
- Отборы пользователя по возможности переносятся внутрь запроса: в условие
ГДЕили в параметры виртуальной таблицы регистра. - Процессор компоновки выполняет итоговый запрос, считает ресурсы по группировкам и передаёт элементы результата процессору вывода.
Посмотреть, какой запрос на самом деле ушёл в базу, можно в отладчике: остановитесь после КомпоновщикМакета.Выполнить(...) и раскройте у макета компоновки коллекцию наборов данных — там лежит итоговый текст запроса.
Автозаполнение и фигурные скобки
Флажок Автозаполнение у набора-запроса заставляет СКД самой описать поля и разрешить отбор по ним. Для большинства отчётов этого достаточно.
Если нужно управлять вручную, в тексте запроса используют фигурные скобки. Конструктор запроса в режиме СКД показывает для этого вкладку Компоновка данных: на ней отмечают обязательные таблицы и условия, которые СКД может накладывать по желанию пользователя. Такие условия оборачиваются в { } и подключаются, только когда пользователь включил соответствующий отбор.
Параметры виртуальных таблиц
Когда в запросе есть виртуальная таблица регистра, например Обороты(&НачалоПериода, &КонецПериода, , ), СКД сама создаёт параметры НачалоПериода и КонецПериода на вкладке «Параметры». Отбор по измерению регистра она переносит в условие виртуальной таблицы — это быстрее, чем фильтровать готовый результат.
Поля, ресурсы и параметры: на чём держится настройка отчёта
Поля набора данных
У каждого поля в наборе есть путь (имя, по которому к нему обращаются настройки), заголовок и ограничения. В колонке ограничений снимают флажки «Поле», «Условие», «Группировка», «Порядок», если пользователю не нужно, например, группировать по сумме документа.
Ресурсы
Ресурс — поле, для которого считаются итоги в каждой группировке. Если сумму не объявить ресурсом, в строках группировки она будет пустой: СКД не знает, как её сворачивать.
Функции агрегирования ресурсов: Сумма, Количество, Максимум, Минимум, Среднее. Для подсчёта уникальных значений — Количество(Различные Поле).
Колонка «Рассчитывать по» ограничивает, в каких группировках выводить итог. Классический пример — цена: в группировке по номенклатуре её показать можно, а складывать цены по контрагенту бессмысленно.
Процент и долю нельзя делать ресурсом с функцией «Сумма»: в итоге получится сумма процентов. Ресурс-процент считают от итогов:
ВЫБОР
КОГДА Сумма(Себестоимость) = 0 ТОГДА 0
ИНАЧЕ (Сумма(Выручка) - Сумма(Себестоимость)) / Сумма(Себестоимость) * 100
КОНЕЦ
Доля строки в общем итоге — через функцию ВычислитьВыражение:
Сумма(Выручка) / ВычислитьВыражение("Сумма(Выручка)", , "ОбщийИтог") * 100
Вычисляемые поля
Вычисляемое поле живёт на уровне схемы, а не запроса. Его выражение пишут на языке выражений СКД, похожем на язык запросов. Подходит для простых формул: наценка в рублях, признак просрочки, склейка строк.
Тяжёлую логику лучше переносить в запрос: вычисляемое поле считается для каждой строки результата уже после выборки.
Параметры
Параметр задают на вкладке «Параметры». Полезные приёмы:
- 📅 параметр типа
СтандартныйПериоддаёт пользователю удобный выбор периода, аНачалоПериодаиКонецПериодаполучают значения выражениями&Период.ДатаНачалаи&Период.ДатаОкончания; - 🔒 флажок «Ограничение доступности» прячет параметр от пользователя — так скрывают служебные параметры, заполняемые выражением;
- 📋 флажок «Доступен список значений» позволяет передать несколько значений сразу, в запросе тогда пишут
В (&Параметр).
Параметр типа «Дата» с составом «Дата» передаёт начало суток. Если подставить его в КонецПериода как есть, документы последнего дня после 00:00:00 в отчёт не попадут. Используйте КонецПериода(&Дата, "День") в выражении параметра или стандартный период.
Группировки и иерархии в структуре отчёта
Структура отчёта настраивается на вкладке «Настройки». Её корень — сам отчёт, ниже добавляют элементы:
| Элемент структуры | Когда нужен |
|---|---|
| Группировка | Обычный отчёт-список с итогами по уровням |
| Таблица | Кросс-таблица: строки по одному полю, колонки по другому (например, номенклатура × месяцы) |
| Диаграмма | Графическое представление тех же ресурсов |
| Детальные записи | Группировка без полей: выводит строки набора как есть |
Типы группировки по полю
У поля группировки есть тип:
- Без иерархии (элементы) — только сами значения, иерархия справочника игнорируется;
- Иерархия — группы справочника и элементы внутри, с итогами по группам;
- Только иерархия — одни группы, без конечных элементов.
Для группировки по периоду (месяц, квартал) задают тип дополнения: если продаж в марте не было, СКД может всё равно вывести март с нулём. Это нужно для графиков и сравнений по периодам.
Вложенность и варианты
Группировки вкладываются друг в друга: «Контрагент → Договор → Документ». У каждой можно задать свои отборы, сортировку и условное оформление. Набор настроек сохраняется как вариант отчёта, а пользователь может сохранить свои настройки поверх варианта.
Как собрать отчёт на СКД: от простого к сложному
Пример 1. Отчёт без кода
- Создайте внешний отчёт или отчёт в конфигурации и откройте на вкладке «Основные» основную схему компоновки данных.
- Добавьте набор данных «Запрос» и через конструктор выберите виртуальную таблицу оборотов нужного регистра накопления.
- Включите поля измерений и обороты, на вкладке «Ресурсы» нажмите кнопку добавления всех ресурсов — числовые поля получат функцию
Сумма. - На вкладке «Параметры» замените
НачалоПериодаиКонецПериодавыражениями от параметра типаСтандартныйПериод. - На вкладке «Настройки» откройте конструктор настроек, выберите тип «Список», укажите группировку и поля.
- Запустите отчёт в режиме 1С:Предприятие и нажмите
Сформировать.
Имена регистров и полей берите из своей конфигурации: в БП, ЗУП и УТ они разные.
Пример 2. Два набора данных
Классическая задача — план и факт. План лежит в одном регистре, факт в другом, периодичность разная. Вместо громоздкого запроса с полным соединением делают два набора и связывают их на вкладке «Связи наборов данных» по общему измерению.
Связь в СКД работает как левое соединение от источника к приёмнику. Если на одну строку источника приходится несколько строк приёмника, строки источника размножатся. Поэтому второй набор сворачивают до ключа связи прямо в запросе — суммируют и группируют по полю связи.
Альтернатива — набор «Объединение»: оба запроса дают одинаковые поля, а СКД складывает строки и считает итоги. Для плана-факта это часто надёжнее связи.
Пример 3. Вывод результата из кода
Когда отчёт формируется программно или результат нужен в другом месте, конвейер собирают вручную. Код выполняется на сервере, например в модуле объекта отчёта:
СхемаКомпоновки = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновки.НастройкиПоУмолчанию;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ДокументРезультат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Чтобы получить не табличный документ, а таблицу значений, меняют генератор макета и процессор вывода:
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки, , ,
Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
Результат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Так СКД используют как «умный запрос»: отборы пользователь задаёт в настройках, а дальше таблица уходит в обработку, печатную форму или обмен.
Значение параметра из кода задают через настройки: Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Организация", Организация); — до вызова компоновщика макета.
Как ускорить СКД на больших базах
Медленный отчёт на СКД почти всегда медленный из-за запроса, а не из-за самой компоновки. Порядок проверки:
- Ограничьте период. Параметры периода делайте обязательными и не оставляйте пустыми: пустая дата начала означает выборку за всю историю.
- Отбирайте внутри виртуальных таблиц. Поля, по которым пользователь чаще всего фильтрует, берите из измерений регистра — тогда отбор уйдёт в параметры виртуальной таблицы.
- Не тяните лишние таблицы. Каждое разыменование через точку (
Номенклатура.Родитель.Наименование) добавляет соединение. Оставляйте в схеме только поля, которые реально нужны. - Не помечайте таблицы обязательными без причины. Обязательная таблица остаётся в запросе, даже если её поля не выбраны.
- Осторожно с детальными записями. Миллион строк в табличном документе съест память клиента и сервера раньше, чем запрос закончит работу.
- Выносите формулы в запрос. Вычисляемые поля и
ВычислитьВыражениесчитаются по строкам результата, на больших объёмах это заметно. - Пакетный запрос с временными таблицами в наборе данных допустим: тяжёлую подготовку вынесите во временную таблицу с индексом по полю соединения.
Замеры делайте на копии базы или в нерабочее время. Тяжёлый отчёт за несколько лет на рабочем сервере тормозит всех пользователей, пока выполняется.
Чтобы найти узкое место, используйте замер производительности в отладчике и технологический журнал с событиями долгих запросов. Тогда видно, какой именно запрос из макета компоновки тормозит.
Ошибки, на которых спотыкаются в СКД
Ещё одна частая ловушка — отбор в запросе вместо параметра. Условие ГДЕ по полю регистра без фигурных скобок работает всегда, и пользователь не может его снять. Если отбор должен быть настраиваемым, отдайте его в компоновку.
Частые вопросы о системе компоновки
Можно ли использовать СКД в управляемых формах вне отчёта?
Чем вариант отчёта отличается от пользовательских настроек?
Работает ли расшифровка, если отчёт формируется из кода?
ДанныеРасшифровкиКомпоновкиДанных и сохранить его вместе с табличным документом для обработчика расшифровки.