При разработке отчетов в Системе компоновки данных (СКД) программисты часто сталкиваются с задачей, когда показатели нужно расположить не горизонтально (в виде колонок), а вертикально (в виде строк). Классический пример — отчет по движению денежных средств или товаров в разрезе организаций, где в шапке (в колонках) должны идти организации, а в строках — три показателя: Остаток на начало, Оборот и Остаток на конец.
В этой статье мы подробно разберем, как решить эту задачу в СКД. Мы проанализируем три различных способа: от самого простого и правильного (средствами настроек компоновки) до сложного (через объединение запросов и построение таблицы показателей).
Это самый простой, элегантный и рекомендуемый способ. Вместо того чтобы переписывать запрос и искусственно создавать строки через ОБЪЕДИНИТЬ ВСЕ, мы предоставим СКД возможность самой развернуть выбранные ресурсы по вертикали.
Рассмотрим по шагам, как это настроить:
ДенежныеСредстваОстаткиИОбороты). Нам понадобятся поля: Организация, СуммаНачальныйОстаток, СуммаОборот (или отдельно СуммаПриход и СуммаРасход) и СуммаКонечныйОстаток.
ВЫБРАТЬ
ДенежныеСредстваОстаткиИОбороты.Организация КАК Организация,
ДенежныеСредстваОстаткиИОбороты.СуммаНачальныйОстаток КАК СуммаНачальныйОстаток,
ДенежныеСредстваОстаткиИОбороты.СуммаОборот КАК СуммаОборот,
ДенежныеСредстваОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаКонечныйОстаток
ИЗ
РегистрНакопления.ДенежныеСредства.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Авто, , ) КАК ДенежныеСредстваОстаткиИОбороты
Сумма(СуммаНачальныйОстаток)Сумма(СуммаОборот)Сумма(СуммаКонечныйОстаток)Организация.СуммаНачальныйОстаток, СуммаОборот, СуммаКонечныйОстаток.Запустим отчет. Мы увидим, что СКД автоматически сформировала таблицу, где в колонках выведены названия организаций, а в строках друг под другом отображаются наши ресурсы. Чтобы изменить системные названия (например, вместо "Сумма начальный остаток" выводить понятное "Остаток на начало"), перейдите на вкладку Наборы данных и в колонке Заголовок для соответствующих полей укажите нужные наименования.
Иногда требуется расположить вертикально только определенную группу ресурсов, оставив остальные показатели в горизонтальных колонках. Для этого можно использовать механизм группировки выбранных полей.
Разберем, как это сделать:
При таком подходе СКД объединит указанные ресурсы в вертикальный столбец внутри общей горизонтальной структуры отчета, что дает колоссальную гибкость при проектировании сложных аналитических форм.
Бывают ситуации, когда в отчете необходимо вывести не просто три стандартных ресурса, а сложную структуру данных, где показатели собираются из разных таблиц (как в сообщении 28: остатки берутся из регистра денежных средств, а обороты детализируются по статьям движения денежных средств: "Поступление от торговой деятельности", "Расчеты с поставщиками", "Зарплата" и т.д.).
Если мы попробуем решить эту задачу простым объединением (UNION ALL) в одном запросе, мы неизбежно столкнемся с проблемой: если по какой-то организации нет остатка или оборота на определенный период, строка с этим показателем просто исчезнет из отчета (о чем и пишет автор форума в сообщениях 22 и 26).
Чтобы гарантировать вывод всех строк-показателей (даже если они равны нулю), мы применим профессиональный паттерн проектирования в СКД — Связь с набором данных "Показатели".
Проанализируем этот алгоритм подробно:
ВЫБРАТЬ "1. Остаток на начало" КАК Показатель, 1 КАК НомерСтроки
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "2. Поступление денежных средств", 2
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "3. Расчеты с поставщиками", 3
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "4. Зарплата", 4
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "5. Остаток на конец", 5
// Получаем начальные остатки
ВЫБРАТЬ
"1. Остаток на начало" КАК Показатель,
Остатки.Организация КАК Организация,
Остатки.СуммаНачальныйОстаток КАК Сумма
ИЗ
РегистрНакопления.ДенежныеСредства.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , ) КАК Остатки
ОБЪЕДИНИТЬ ВСЕ
// Получаем приходы по торговой деятельности
ВЫБРАТЬ
"2. Поступление денежных средств",
Обороты.Организация,
Обороты.СуммаОборот
ИЗ
РегистрНакопления.ДвиженияДенежныхСредств.Обороты(&НачалоПериода, &КонецПериода, , СтатьяДвиженияДенежныхСредств В (&СтатьиДоходов)) КАК Обороты
ОБЪЕДИНИТЬ ВСЕ
// Получаем расходы на зарплату
ВЫБРАТЬ
"4. Зарплата",
Обороты.Организация,
Обороты.СуммаОборот
ИЗ
РегистрНакопления.ДвиженияДенежныхСредств.Обороты(&НачалоПериода, &КонецПериода, , СтатьяДвиженияДенежныхСредств В (&СтатьиЗарплаты)) КАК Обороты
ОБЪЕДИНИТЬ ВСЕ
// Получаем конечные остатки
ВЫБРАТЬ
"5. Остаток на конец",
Остатки.Организация,
Остатки.СуммаКонечныйОстаток
ИЗ
РегистрНакопления.ДенежныеСредства.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , ) КАК Остатки
Показатель = ПоказательПоказатель из Набора №1. Чтобы строки выводились в правильном порядке, в настройках сортировки этой группировки укажите сортировку по полю НомерСтроки.Организация.Сумма.Благодаря левому соединению связей наборов данных СКД, даже если по Организации №2 не было выплат по зарплате или остаток равен нулю, строка "4. Зарплата" все равно отобразится в отчете, а на пересечении с этой организацией будет пустое значение или ноль.
Чтобы вместо пустых ячеек (значений NULL) в отчете выводились аккуратные нули, выполним простую настройку:
На вкладке Ресурсы для рассчитываемого поля Сумма в графе Выражение напишем функцию проверки на пустое значение:
ЕстьNull(Сумма(Сумма), 0)
Также мы можем использовать вкладку Условное оформление в настройках отчета. Добавим новое оформление, выберем свойство Формат и в поле Представление нуля укажем символ "0" или прочерк "-". В условиях оформления укажем, что оно применяется, если значение ресурса не заполнено.