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