СКД 1С — система компоновки данных, механизм платформы «1С:Предприятие 8», на котором построено большинство отчётов в типовых конфигурациях. Программист описывает в схеме, откуда брать данные и что можно посчитать. Группировки, отборы, сортировку и оформление пользователь потом меняет сам, в настройках отчёта, без правки кода. Ниже — из каких частей состоит схема компоновки данных, что происходит после нажатия «Сформировать», как увидеть реальный запрос отчёта и на чём чаще всего спотыкаются.
Чаще всего — в отчётах. Если у отчёта есть кнопка «Настройки», а в ней отборы, поля и группировки, перед вами СКД. Так устроены отчёты БП 3.0, УТ 11, ERP, КА 2 и других конфигураций на БСП, а также универсальный отчёт по любому справочнику, документу или регистру.
Второе место — динамические списки. Отбор, сортировка, условное оформление и группировка в команде «Ещё → Настроить список» — это настройки компоновки данных. Из кода список управляется теми же объектами: Список.КомпоновщикНастроек, ЭлементОтбораКомпоновкиДанных.
Третье — программная обработка: СКД отдаёт результат и в таблицу или дерево значений, когда нужны многоуровневые итоги или отбор, который настраивает пользователь.
Схема — это макет с типом «Схема компоновки данных» внутри отчёта, обработки или в общих макетах. У отчёта одна схема назначается основной (свойство «Основная схема компоновки данных») — по ней платформа и формирует результат. Закладки конструктора схемы почти один в один совпадают с её частями.
Набор данных отвечает на вопрос «откуда брать строки». Видов три:
ОБЪЕДИНИТЬ ВСЕ. Например, план из одного регистра и факт из другого. Поля вложенных наборов сопоставляются по пути к данным.В тексте запроса набора работает расширение языка запросов для СКД — фрагменты в фигурных скобках, например {ГДЕ Продажи.Склад.*}. Они подсказывают компоновщику, какие поля и условия можно менять из настроек; при автозаполнении большую часть этой работы СКД делает сама.
Если наборов несколько, связи задают, как сопоставлять их строки: набор-источник, набор-приёмник и выражения с обеих сторон — обычно одно и то же поле, например Номенклатура. Связь работает как левое соединение: все строки источника остаются, данные приёмника подтягиваются там, где нашлась пара. Флажок «Обязательная связь» делает соединение внутренним. Связанные наборы выполняются отдельными запросами, соединяет их процессор компоновки. Для запроса и внешнего набора это единственный путь, а два регистра одной базы проще соединить в одном запросе.
У каждого поля набора есть заголовок, ограничения использования (можно ли выбрать его в отборе, группировке, сортировке), роль и оформление — подробнее в статье про поля СКД. Вычисляемые поля — те, которых в наборе нет: их значение считается выражением на языке выражений СКД, например ВЫБОР КОГДА Количество = 0 ТОГДА 0 ИНАЧЕ Сумма / Количество КОНЕЦ. В выражении можно вызвать экспортную функцию общего модуля через имя модуля, но она выполнится для каждой строки результата.
Ресурс — поле, по которому СКД считает итоги на каждом уровне группировок. Выражение ресурса — агрегатная функция: Сумма(Сумма), Количество(Различные Номенклатура), Максимум(Цена). Для средней цены правильный ресурс — не Среднее(Цена), а ВЫБОР КОГДА Сумма(Количество) = 0 ТОГДА 0 ИНАЧЕ Сумма(Сумма) / Сумма(Количество) КОНЕЦ: среднее арифметическое цен не учитывает объёмы. Колонка «Рассчитывать по» ограничивает группировки, в которых ресурс считается, — цену, например, есть смысл показывать только в строке номенклатуры, а не в итоге по складу.
Параметры из текста запроса (&НачалоПериода, &КонецПериода) появляются на закладке «Параметры» сами. Туда же добавляют свои: параметр Период типа «Стандартный период», а у НачалоПериода в колонке «Выражение» пишут &Период.ДатаНачала. Пользователь выбирает один период, запрос получает две даты. Служебный параметр скрывают флажком «Ограничение доступности» и заполняют из кода. Подробнее — в статье о параметрах СКД.
Настройки описывают, что именно показать: структуру отчёта (группировки, таблицы, диаграммы), выбранные поля, отбор, сортировку, условное оформление и параметры вывода — заголовок, расположение итогов, макет оформления. Один набор настроек — это вариант отчёта. Разработчик задаёт варианты в конструкторе, пользователь сохраняет свои. Про устройство структуры — в статье о группировках СКД, про варианты — в статье о вариантах отчёта.
Когда стандартного вывода мало — нужна шапка как в печатной форме, объединённые ячейки, особый вид строки итога, — на закладке «Макеты» задают свою область табличного документа для поля, группировки или заголовка. Подробно — в статье про макет СКД.
После нажатия «Сформировать» платформа проходит цепочку: схема и настройки → макет компоновки → процессор компоновки → табличный документ. Ту же цепочку повторяют руками, когда отчёт формируют из кода.
| Шаг | Объекты встроенного языка | Что происходит |
|---|---|---|
| 1. Исходные данные | СхемаКомпоновкиДанных, НастройкиКомпоновкиДанных | Схема берётся из макета отчёта, настройки — из КомпоновщикНастроекКомпоновкиДанных: вариант плюс изменения пользователя. |
| 2. Компоновка макета | КомпоновщикМакетаКомпоновкиДанных → МакетКомпоновкиДанных | Схема и настройки превращаются в макет: готовые тексты запросов, значения параметров, описание областей вывода. Поля, не нужные в текущих настройках, в запрос не попадают, отборы по возможности становятся условиями запроса. |
| 3. Получение данных | ПроцессорКомпоновкиДанных | Выполняет запросы, принимает внешние наборы, связывает наборы между собой, считает вычисляемые поля и ресурсы, раскладывает строки по группировкам. |
| 4. Вывод | ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент | Выводит результат в табличный документ. Для таблицы или дерева значений — ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. |
Отсюда главное свойство СКД: текст запроса в схеме — заготовка. Настоящий запрос собирается на втором шаге и зависит от варианта. Поэтому один отчёт летает с одними настройками и тормозит с другими — например, если в группировку добавили поле вроде Номенклатура.Производитель.Страна: каждое обращение через точку по ссылке — ещё одно соединение с таблицей.
Когда отчёт тормозит или показывает не те цифры, первым делом смотрят итоговый текст запроса. Функция ниже проходит второй шаг цепочки и возвращает тексты запросов из макета вместе со значениями параметров. Её кладут в общий модуль с флажками «Сервер», «Внешнее соединение» и «Клиент (обычное приложение)», без «Вызов сервера». Иначе вызов из модуля объекта отчёта не скомпилируется в обычном приложении и во внешнем соединении:
// Общий модуль ОтладкаСКД.
// Свойства модуля: «Сервер», «Внешнее соединение», «Клиент (обычное приложение)» - Истина;
// «Вызов сервера» - Ложь (как у серверных модулей БСП).
// Платформа 8.3.6 и выше (СтрСоединить).
// Возвращает тексты запросов, которые СКД выполнит для переданных
// схемы и настроек, и значения параметров этих запросов.
//
// Параметры:
// Схема - СхемаКомпоновкиДанных
// Настройки - НастройкиКомпоновкиДанных
//
// Возвращаемое значение:
// Строка
//
Функция ЗапросыМакета(Схема, Настройки) Экспорт
// Шаг 2 цепочки компоновки: схема + настройки -> макет.
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);
Строки = Новый Массив;
ДобавитьЗапросыНаборов(МакетКомпоновки.НаборыДанных, Строки);
Строки.Добавить("// Параметры макета:");
Для Каждого Параметр Из МакетКомпоновки.ЗначенияПараметров Цикл
Строки.Добавить("// &" + Параметр.Имя + " = " + Строка(Параметр.Значение));
КонецЦикла;
Возврат СтрСоединить(Строки, Символы.ПС);
КонецФункции
Процедура ДобавитьЗапросыНаборов(НаборыДанных, Строки)
Для Каждого Набор Из НаборыДанных Цикл
Если ТипЗнч(Набор) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
Строки.Добавить("// Набор данных: " + Набор.Имя);
Строки.Добавить(Набор.Запрос);
Строки.Добавить("");
ИначеЕсли ТипЗнч(Набор) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных") Тогда
// У объединения запросы лежат во вложенных наборах.
ДобавитьЗапросыНаборов(Набор.Элементы, Строки);
Иначе
// Набор-объект: строки приходят из кода, запроса нет.
Строки.Добавить("// Набор данных " + Набор.Имя + ": внешний, без запроса");
Строки.Добавить("");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Вызывают её из модуля объекта отчёта, в обработчике ПриКомпоновкеРезультата. Стандартное формирование не отключается, тексты запросов уходят в журнал регистрации:
// Модуль объекта отчёта. Временная вставка на время отладки.
// Если ПриКомпоновкеРезультата в модуле уже есть (в типовых отчётах часто есть),
// новую процедуру не создавайте: добавьте блок Попытка в начало существующей.
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Попытка
Схема = ПолучитьМакет(Метаданные().ОсновнаяСхемаКомпоновкиДанных.Имя);
ТекстЗапросов = ОтладкаСКД.ЗапросыМакета(Схема, КомпоновщикНастроек.ПолучитьНастройки());
ЗаписьЖурналаРегистрации("ОтладкаСКД", УровеньЖурналаРегистрации.Информация, , ,
ТекстЗапросов);
Исключение
// Отладка не должна ломать формирование отчёта.
ЗаписьЖурналаРегистрации("ОтладкаСКД", УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// СтандартнаяОбработка не трогаем: отчёт сформируется как обычно.
КонецПроцедуры
#КонецЕсли
Если в существующем обработчике своя компоновка (СтандартнаяОбработка = Ложь), передавайте в ОтладкаСКД.ЗапросыМакета те же схему и настройки, с которыми он работает.
КомпоновщикМакета.Выполнить(Схема, Настройки) — второй шаг цепочки. Результат — МакетКомпоновкиДанных: заготовок в нём уже нет, только то, что пойдёт в работу.МакетКомпоновки.НаборыДанных — наборы макета, а не схемы. Свойство Запрос набора-запроса содержит итоговый текст: без лишних полей, с условиями из отбора пользователя.ДобавитьЗапросыНаборов нужна для объединений: их запросы лежат уровнем ниже. У набора-объекта запроса нет, выводится только имя.МакетКомпоновки.ЗначенияПараметров — значения параметров, включая созданные компоновщиком для условий отбора. Без них текст запроса в консоли не выполнить.Метаданные().ОсновнаяСхемаКомпоновкиДанных.Имя — имя основной схемы без строковой константы, а настройки — из КомпоновщикНастроек того же отчёта, с ними платформа и формирует результат.Попытка … Исключение — если основной схемы нет или её подменяют программно, в журнал уйдёт ошибка, а формирование отчёта продолжится.Текст из журнала регистрации копируют в консоль запросов, подставляют параметры и замеряют. После отладки вставку убирают.
Сумма(Сумма) честно складывает дубли.#Если.ПриКомпоновкеРезультата в модуле отчёта даёт ошибку «Процедура или функция с указанным именем уже определена». В типовых отчётах ERP, УТ 11, КА 2 обработчик часто уже есть — отладочный код добавляют в него.Отчёт «запрос плюс табличный документ» жёстко задаёт вид: новая колонка или другая группировка — это правка кода. В отчёте на СКД пользователь сам меняет поля, отборы и группировки, сохраняет варианты, получает расшифровку по двойному клику. Ручной вывод по макету остаётся для печатных форм, где важен точный внешний вид.
Да. Схема компоновки данных устроена одинаково в обычном и управляемом приложении, механизм появился ещё в платформе 8.1. Отличаются форма отчёта и работа с настройками на клиенте.
Да, как внешний отчёт: схема создаётся в конфигураторе, но файл подключается к базе без обновления конфигурации. Если конфигуратора нет, остаются настройка готовых отчётов и универсальный отчёт — варианты перечислены в статье о том, как сделать отчёт в 1С.
При компоновке макета передайте тип генератора ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений, а для вывода используйте ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений с методом УстановитьОбъект. Для нескольких уровней группировок удобнее дерево значений.
Если отчёт собирает данные из нескольких регистров или считает то, чего нет в типовых отчётах, быстрее отдать схему программисту. На 1c-only.ru задачу по разработке отчётов на СКД и обработок оценивают бесплатно, ответ приходит в течение рабочего дня: опишите колонки, группировки и отборы и разместите задачу. Если тормозит уже существующий отчёт, посмотрите услугу «1С тормозит».
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.