При разработке сложных отчетов в системе компоновки данных (СКД) (поможет инструмент отладки запросов и схем СКД) мы часто сталкиваемся с ситуацией, когда под одним названием отчета необходимо объединить логически разные, но тематически связанные данные. Например, один вариант должен показывать продажи товаров, а другой — остатки на складах, причем структуры запросов и источники данных существенно различаются. Разберем подробно, как можно элегантно решить задачу разделения наборов данных по вариантам отчета, не создавая при этом множество отдельных объектов в конфигурации.
Это один из самых гибких способов, который позволяет полностью изолировать логику одного варианта от другого. Рассмотрим этот метод как основной, если наборы данных кардинально отличаются. Вложенная схема — это, по сути, полноценная схема СКД, которую мы вызываем внутри основной.
Разберем по шагам процесс настройки:
Этот метод хорош тем, что НаборДанных1 и НаборДанных2 будут существовать в разных физических схемах, что исключает конфликты имен полей и параметров. Основная схема в данном случае выступает лишь в роли диспетчера вариантов.
Проанализируем ситуацию, когда данные похожи, но выбираются из разных таблиц или с разными условиями. Вместо создания двух наборов данных Запрос, мы можем объединить их в один. Это значительно упрощает поддержку отчета.
Рассмотрим пример построения такого запроса:
ВЫБРАТЬ
"Вариант1" КАК ТипДанных,
Продажи.Номенклатура КАК Номенклатура,
Продажи.КоличествоОборот КАК Показатель
ИЗ
РегистрНакопления.Продажи.Обороты КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"Вариант2",
Закупки.Номенклатура,
Закупки.КоличествоОборот
ИЗ
РегистрНакопления.Закупки.Обороты КАК Закупки
Теперь выясним, как заставить варианты работать раздельно. В настройках СКД для Варианта №1 мы установим фиксированный (недоступный пользователю) отбор по полю ТипДанных Равно "Вариант1". Соответственно, для Варианта №2 установим отбор по значению "Вариант2". СКД достаточно интеллектуальна: при построении итогового SQL-запроса она может отсечь неиспользуемые части объединения, если это позволяют условия.
Часто проблема возникает из-за того, что параметры одного набора данных обязательны, но не нужны в другом варианте. Посмотрим, как это решается средствами расширения языка запросов СКД. Мы можем поместить условия в фигурные скобки {}.
Например, проанализируем такой фрагмент запроса:
ГДЕ {Регистратор.Дата МЕЖДУ &НачалоПериода И &КонецПериода}
Если в настройках конкретного варианта отчета параметры НачалоПериода и КонецПериода не используются и не установлены, СКД просто удалит эту секцию из итогового запроса к базе данных, и ошибка "Параметр не заполнен" не возникнет.
Если нам нужно максимально динамическое поведение, мы можем вмешаться в процесс формирования отчета программно. Для этого будем использовать модуль объекта отчета и обработчик события ПриКомпоновкеРезультата.
Рассмотрим пример кода, который меняет запрос в зависимости от выбранного варианта:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Берем управление в свои руки
// Определяем имя текущего варианта
ИмяВарианта = КомпоновщикНастроек.ЗагруженныеНастройки.ИмяВарианта;
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Если ИмяВарианта = "ПродажиПоСкладам" Тогда
Схема.НаборыДанных.НаборДанных1.Запрос = "ВЫБРАТЬ ... ИЗ Регистр.Продажи";
ИначеЕсли ИмяВарианта = "ОстаткиПоСкладам" Тогда
Схема.НаборыДанных.НаборДанных1.Запрос = "ВЫБРАТЬ ... ИЗ Регистр.ТоварыНаСкладах";
КонецЕсли;
// Далее стандартный код инициализации процессора компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Этот метод позволяет использовать один и тот же набор данных НаборДанных1 в интерфейсе разработчика, но подменять его "начинку" в момент формирования отчета. Это избавляет от путаницы с множеством полей в окне настройки компоновки.
Если вы все же решили использовать два разных набора данных в одной схеме (например, два разных запроса), важно не запутать пользователя. По умолчанию СКД сваливает все доступные поля в одну "кучу".
Выясним, как сделать интерфейс чище:
Таким образом, мы рассмотрели пять различных подходов. Выбор конкретного метода зависит от степени различия ваших данных. Для небольших отличий идеально подходит Объединение с параметрами, а для совершенно разных структур данных — Вложенные схемы или Программная подмена текста запроса.