Схему СКД типового отчёта можно использовать в своём отчёте как готовый источник данных: получить её через Отчеты.ИмяОтчета.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"), переписать настройки под свою задачу, выполнить и вывести результат в таблицу значений. Дальше эта таблица идёт во внешний набор данных итоговой схемы вашего отчёта. Типовой отчёт остаётся на поддержке, а вы получаете его актуальную логику после каждого обновления.

Разберу подход на примере производственного отчёта для 1С:ERP, который собирает данные из шести источников: части считаются своими схемами, части — схемами типовых отчётов.

Когда это оправдано

Копировать типовой запрос в свой отчёт кажется проще, но у копии две проблемы:

  • Объём. Запросы отчётов вроде «Остатки и доступность товаров» в ERP — это сотни строк с временными таблицами и условной логикой. Переносить и отлаживать их дольше, чем использовать готовую схему.
  • Обновления. После каждого обновления конфигурации нужно сверять, что изменилось в типовом запросе. Об этом обычно забывают, и через год отчёт тихо врёт.

Использовать типовую схему разумно, когда типовой отчёт уже считает нужный показатель правильно, а вам нужен этот показатель как часть более сложного расчёта.

Как устроен составной отчёт

Пример задачи: отчёт по выполнению производственных заказов. Источники:

№ДанныеИсточник
1Заказы на производство и их строкиСвоя схема, запрос
2Остатки и доступность товаровСхема типового отчёта ERP
3Этапы производстваСвоя схема, зависит от п. 1
4Нормативы полуфабрикатов (разузлование спецификаций)Своя схема
5Остатки полуфабрикатов на цеховой кладовойСхема типового отчёта
6Факт выполнения этаповСхема типового отчёта, зависит от п. 3
7Время выполненияРасчёт кодом
8Итоговая схема для выводаСвоя схема с внешними наборами

Каждый этап выполняется на сервере и даёт таблицу значений. Результаты ранних этапов становятся отборами поздних: например, характеристики из заказов ограничивают выборку остатков.

Схема СКД типового отчёта: результаты нескольких схем сходятся в итоговую схему отчёта
Схема СКД типового отчёта: результаты нескольких схем сходятся в итоговую схему отчёта

Форму отчёта я в таких случаях делаю простой: фиксированный набор параметров в шапке (период, заказ, номенклатура), без вариантов и пользовательской структуры. Чем меньше вариативность, тем меньше точек, где сложная цепочка может сломаться.

Универсальная функция: выполнить схему в таблицу значений

Чтобы не повторять один и тот же код для каждого этапа, выношу выполнение в функцию.

1С
// Выполняет схему компоновки и возвращает результат в виде таблицы значений.
//
// Параметры:
//  Схема     - СхемаКомпоновкиДанных
//  Настройки - НастройкиКомпоновкиДанных
//  ВнешниеНаборы - Структура, Неопределено - внешние наборы данных схемы.
//
Функция ВыполнитьСхемуВТаблицу(Схема, Настройки, ВнешниеНаборы = Неопределено) Экспорт

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
		Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы, , Истина);

	Результат = Новый ТаблицаЗначений;
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
	ПроцессорВывода.УстановитьОбъект(Результат);
	ПроцессорВывода.Вывести(ПроцессорКомпоновки);

	Возврат Результат;

КонецФункции

Генератор для коллекции значений требует, чтобы в структуре настроек были только группировки без иерархии и итогов, — лучше всего одна группировка «Детальные записи». Четвёртый параметр Инициализировать разрешает функции общих модулей в выражениях схемы: типовые схемы ими пользуются.

Для отладки этапа временно выводите тот же макет в табличный документ обычным генератором — так видно, что вернула схема.

Подготовка настроек типовой схемы

Настройки по умолчанию типового отчёта рассчитаны на показ пользователю: группировки, итоги, оформление. Для нас нужна плоская таблица с конкретными полями.

1С
// Готовит настройки схемы для выгрузки детальных записей с указанными полями.
Функция НастройкиДетальныхЗаписей(Схема, ИменаПолей) Экспорт

	Настройки = Схема.НастройкиПоУмолчанию;

	Настройки.Структура.Очистить();
	Детальные = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	Детальные.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));

	Настройки.Выбор.Элементы.Очистить();
	Для Каждого ИмяПоля Из СтрРазделить(ИменаПолей, ",", Ложь) Цикл
		ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
		ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(СокрЛП(ИмяПоля));
	КонецЦикла;

	Возврат Настройки;

КонецФункции

// Добавляет элемент отбора в настройки компоновки.
Процедура ДобавитьОтбор(Настройки, ИмяПоля, ВидСравнения, Значение = Неопределено) Экспорт

	ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля);
	ЭлементОтбора.ВидСравнения = ВидСравнения;
	ЭлементОтбора.ПравоеЗначение = Значение;
	ЭлементОтбора.Использование = Истина;

КонецПроцедуры

Применение к типовому отчёту «Остатки и доступность товаров»:

1С
	СхемаОстатков = Отчеты.ОстаткиИДоступностьТоваров.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	НастройкиОстатков = НастройкиДетальныхЗаписей(СхемаОстатков,
		"Склад, Номенклатура, Характеристика, Назначение, Доступно");

	// Отбор зависит от результата предыдущего этапа.
	ДобавитьОтбор(НастройкиОстатков, "Характеристика", ВидСравненияКомпоновкиДанных.ВСписке,
		ДанныеПоЗаказам.ВыгрузитьКолонку("Характеристика"));
	ДобавитьОтбор(НастройкиОстатков, "Назначение", ВидСравненияКомпоновкиДанных.НеЗаполнено);

	ОстаткиБезНазначения = ВыполнитьСхемуВТаблицу(СхемаОстатков, НастройкиОстатков);

Имена полей и макета берите из конфигурации: откройте типовой отчёт в конфигураторе и посмотрите поля наборов данных. В разных версиях конфигурации они могут отличаться.

Параметры схемы

Параметры не правьте в самой схеме (Схема.Параметры), а задавайте в настройках:

1С
	НастройкиОстатков.ПараметрыДанных.УстановитьЗначениеПараметра("Период", КонецДня(ДатаОтчета));

Так вы не зависите от того, как разработчики типового отчёта настроили использование параметра.

Свои схемы: разузлование спецификаций

Для нормативов полуфабрикатов нужен обход дерева спецификаций: если в материалах спецификации есть полуфабрикат, который производится по своей спецификации, надо спуститься в неё. В СКД это решается связью набора данных с самим собой на закладке «Связи наборов данных»: источник и приёмник — один набор, связь по полю спецификации-источника полуфабриката, с параметром для списка спецификаций.

Запрос 1С
ВЫБРАТЬ
	Материалы.Ссылка КАК Спецификация,
	Материалы.Номенклатура КАК Номенклатура,
	Материалы.Характеристика КАК Характеристика,
	Материалы.КоличествоУпаковок КАК Норматив,
	ВЫРАЗИТЬ(Материалы.ИсточникПолученияПолуфабриката КАК Справочник.РесурсныеСпецификации) КАК СпецификацияПолуфабриката
ИЗ
	Справочник.РесурсныеСпецификации.МатериалыИУслуги КАК Материалы
ГДЕ
	Материалы.Ссылка В (&МассивСпецификаций)
	И Материалы.СпособПолученияМатериала = ЗНАЧЕНИЕ(Перечисление.СпособыПолученияМатериаловВСпецификации.ПроизвестиПоСпецификации)

Имена реквизитов здесь взяты из ERP 2 и в вашей редакции могут отличаться. Пересчёт количества с учётом входимости узлов в родителя удобнее сделать кодом после выгрузки — СКД отдаёт дерево, но не перемножает нормативы по уровням.

Итоговая схема с внешними наборами

В итоговой схеме отчёта создаются наборы данных типа «Объект» — по одному на каждую подготовленную таблицу, с описанными полями и связями. Таблицы передаются структурой:

1С
	ВнешниеНаборы = Новый Структура;
	ВнешниеНаборы.Вставить("ДанныеПоЗаказам", ДанныеПоЗаказам);
	ВнешниеНаборы.Вставить("ОстаткиБезНазначения", ОстаткиБезНазначения);
	ВнешниеНаборы.Вставить("ЭтапыПроизводства", ЭтапыПроизводства);
	ВнешниеНаборы.Вставить("ФактВыполнения", ФактВыполнения);

	ДанныеРасшифровкиОтчета = Новый ДанныеРасшифровкиКомпоновкиДанных;

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(ИтоговаяСхема, ИтоговыеНастройки, ДанныеРасшифровкиОтчета);

	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборы, ДанныеРасшифровкиОтчета);

	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(Результат);
	ПроцессорВывода.Вывести(ПроцессорКомпоновки);

	АдресДанныхРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиОтчета, УникальныйИдентификатор);

Ключи структуры совпадают с именем объекта в свойствах набора. Данные расшифровки кладутся во временное хранилище — это нужно форме для обработки двойного клика по ячейке.

Производительность составного отчёта

Каждый этап — это отдельный запрос к базе, а результаты держатся в памяти сервера как таблицы значений. На больших периодах это ощутимо, поэтому:

  • Сужайте раньше. Первый этап должен максимально ограничить выборку (заказы за период, по подразделению), а следующие этапы — получать отборы из его результата.
  • Выбирайте только нужные поля. В настройках типовой схемы оставляйте 4–6 полей, а не все доступные: схема с автоматическим заполнением не будет считать лишние ресурсы и соединения.
  • Не дублируйте этапы. Если две части отчёта используют один и тот же результат типовой схемы, выполняйте её один раз и передавайте таблицу дальше.
  • Формируйте в фоне. Для отчёта с несколькими тяжёлыми схемами используйте фоновое формирование, иначе пользователь будет ждать с замороженным окном, а при долгом выполнении сработает таймаут клиента.
  • Замеряйте этапы. На время доводки я пишу длительность каждого этапа в журнал регистрации — сразу видно, какая схема съедает время.

Типичные ошибки и риски

  • Схема без модуля. Многие типовые отчёты дорабатывают компоновку в модуле: подставляют параметры, готовят данные, переопределяют настройки. Голая схема может вернуть не то, что показывает отчёт. Читайте модуль и сверяйте результат с типовым отчётом на тех же данных.
  • Иерархия и итоги в настройках. Генератор для коллекции значений не умеет иерархические группировки — очищайте структуру.
  • Поле не найдено. После обновления типовой схемы поле переименовали. Проверяйте наличие полей в Схема.НаборыДанных или ловите ошибку и пишите понятное сообщение.
  • Огромные списки в отборе «В списке». Если в отбор уходят тысячи значений, запрос тяжелеет. Сужайте данные ранними этапами.
  • Права доступа. Типовая схема выполняется с правами текущего пользователя. Если у него нет прав на часть данных, итоги разойдутся с ожиданием.
Типовая схема — это зависимость от чужого кода. Она избавляет от копирования, но требует проверки после каждого обновления.

Такие составные отчёты я делаю в рамках разработки отчётов на СКД и проектов внедрения 1С:ERP, где типовой функционал нужно дополнить без снятия с поддержки.

Итог

  • Схема типового отчёта доступна через Отчеты.Имя.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных") без изменения конфигурации.
  • Для выгрузки в таблицу значений используйте ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений и плоскую структуру настроек.
  • Отборы и параметры задавайте в настройках, а не правкой схемы.
  • Результаты этапов передавайте в итоговую схему как внешние наборы данных.
  • Проверяйте модуль типового отчёта и сверяйте результат после каждого обновления.