При разработке аналитических отчетов в 1С часто возникает задача: вывести в строках период (например, день или месяц), в первой колонке показать общий итог по продажам за этот день, а правее развернуть динамические колонки по разрезам доставки (службам, складам или курьерам) с количеством отгрузок. При этом количество служб заранее неизвестно, а общий объем продаж не должен дублироваться под каждой службой доставки.
Если подойти к задаче классическим способом и просто соединить продажи с отгрузками через ЛЕВОЕ СОЕДИНЕНИЕ по периоду, то на уровне детальных записей данные о продажах размножатся на количество строк отгрузок. Если затем построить кросс-таблицу, платформа попытается вывести ресурс продаж под каждой динамической группировкой или выдаст неверные итоги при сворачивании за более крупные интервалы. Разберем правильные архитектурные подходы в Системе компоновки данных, позволяющие получить корректный результат без ручной отрисовки макетов.
Проанализируем базовый и наиболее универсальный способ, основанный на конструкции ОБЪЕДИНИТЬ ВСЕ и правильной настройке структуры кросс-таблицы. Чтобы продажи не привязывались к конкретным службам доставки, мы формируем две независимые ветки данных внутри одного запроса. В первой ветке выбираются продажи, а поле аналитики заполняется пустым значением. Во второй ветке выбираются отгрузки с заполненной службой доставки, а поле продаж обнуляется.
Посмотрим на пример запроса для схемы компоновки данных:
ВЫБРАТЬ
Продажи.Период КАК Период,
ВЫРАЗИТЬ(NULL КАК Справочник.СлужбыДоставки) КАК Служба,
Продажи.Количество КАК Продано,
0 КАК Отгружено
ИЗ
РегистрНакопления.Продажи КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Отгрузки.Период,
Отгрузки.Служба,
0,
Отгрузки.Количество
ИЗ
РегистрНакопления.Отгрузки КАК Отгрузки
Обратим внимание на явное приведение типа для пустого поля через ВЫРАЗИТЬ(NULL КАК ...). Если оставить просто NULL, платформа может определить тип поля как Неопределено, что приведет к сложностям при дальнейшей сортировке или фильтрации в отчете.
Разберем по шагам дальнейшую настройку схемы компоновки данных:
Служба в колонке «Роль» обязательно установим флажок Игнорировать значения NULL. Это исключит появление отдельной пустой колонки со значением «<Не указано>» в динамической части отчета.Продано и Отгружено с функцией Сумма(...).Период.Продано;
вторая группировка колонок создается по полю Служба, а в ее Выбранные поля помещается только ресурс Отгружено.Автополе. Если этого не сделать, платформа принудительно выведет оба ресурса в каждой колонке.В результате такого построения кросс-таблица сформирует ровно один столбец с продажами сразу после даты, а затем динамически развернет столько колонок со службами доставки, сколько будет найдено в выборке за указанный интервал.
Рассмотрим альтернативный вариант, который позволяет избежать объединения разнородных таблиц в одном SQL-запросе. СКД умеет самостоятельно связывать данные на уровне итоговых записей. Для этого мы создаем два независимых набора данных типа «Набор данных — запрос»:
Период и Продано.Период, Служба и Отгружено.На вкладке Связи наборов данных настраиваем связь источника «Продажи» с приемником «Отгрузки» по полю Период. Система автоматически агрегирует продажи строго до уровня периода, а отгрузки — до уровня периода и службы доставки. В структуре отчета повторяется настройка с параллельными колонками, описанная в первом решении.
Проанализируем особенности поведения платформы при расчете горизонтальных итогов в подобных кросс-таблицах:
Продано в графе «Рассчитывать по...» рекомендуется явно указать группировку Период и Общий итог, убрав оттуда группировку Служба. Это гарантирует, что показатель продаж ни при каких обстоятельствах не попадет в динамические ветки колонок.Описанные подходы позволяют полностью отказаться от создания жестких нетиповых макетов компоновки, сохраняя гибкость отчета, возможность смены периодичности и пользовательскую настройку группировок.