Как в СКД вывести разные ресурсы регистра в строки таблицы по месяцам?

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов на Системе компоновки данных (СКД) часто возникает задача представить данные в виде кросс-таблицы, где в строках должны располагаться не только измерения, но и названия различных ресурсов. Рассмотрим ситуацию, когда у нас есть регистр сведений с измерениями Номенклатура и Дата, а также несколькими ресурсами (например, Ресурс1, Ресурс2, Ресурс3). Нам необходимо получить таблицу, где названия ресурсов идут по вертикали, а даты (месяцы) — по горизонтали.

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

Способ 1: Использование объединения запросов (UNION ALL)

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

Разберем, как подготовить такой запрос. Мы создадим виртуальное поле НаименованиеРесурса и общее поле ЗначениеРесурса. Проанализируем пример кода запроса:


ВЫБРАТЬ
    "Ресурс 1" КАК НаименованиеРесурса,
    Регистр.Номенклатура КАК Номенклатура,
    Регистр.Дата КАК Период,
    НАЧАЛОПЕРИОДА(Регистр.Дата, МЕСЯЦ) КАК Месяц,
    Регистр.Ресурс1 КАК ЗначениеРесурса
ИЗ
    РегистрСведений.ИмяВашегоРегистра КАК Регистр

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Ресурс 2",
    Регистр.Номенклатура,
    Регистр.Дата,
    НАЧАЛОПЕРИОДА(Регистр.Дата, МЕСЯЦ),
    Регистр.Ресурс2
ИЗ
    РегистрСведений.ИмяВашегоРегистра КАК Регистр

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Ресурс 3",
    Регистр.Номенклатура,
    Регистр.Дата,
    НАЧАЛОПЕРИОДА(Регистр.Дата, МЕСЯЦ),
    Регистр.Ресурс3
ИЗ
    РегистрСведений.ИмяВашегоРегистра КАК Регистр

После того как запрос написан, выполним следующие настройки в схеме компоновки данных:

  1. Перейдем на вкладку Ресурсы и добавим поле ЗначениеРесурса с выражением СУММА(ЗначениеРесурса).
  2. На вкладке Настройки создадим структуру типа Таблица.
  3. В Строки таблицы добавим группировку по полю НаименованиеРесурса, а внутрь неё — группировку по полю Номенклатура.
  4. В Колонки таблицы добавим группировку по полю Месяц.
  5. В Выбранные поля добавим наш ресурс ЗначениеРесурса.

Важный момент: Если для поля Месяц в настройках группировки установить "Тип дополнения" — "Месяц", СКД автоматически создаст колонки для тех периодов, в которых данных нет, что обеспечит непрерывность календаря в отчете.

Способ 2: Обработка пропусков в данных (получение последнего значения)

Часто возникает вопрос: что делать, если значение ресурса было введено в январе, а в феврале оно не менялось и новой записи в регистре нет? По умолчанию в кросс-таблице за февраль будет пусто. Чтобы "протянуть" значение из предыдущих периодов, воспользуемся классическим приемом получения среза последних на каждую дату.

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

  1. Создадим первый набор данных (запрос) "Календарь", который выбирает все месяцы из справочника или сгенерированной временной таблицы.
  2. Создадим второй набор данных "Данные" по нашему регистру.
  3. В связях укажем, что "Календарь" является источником, а "Данные" — приемником.
  4. Условие связи: Календарь.Месяц >= Данные.Месяц.
  5. В параметрах связи для получения только последней записи используем расчет максимальной даты.

Это позволит реализовать логику, аналогичную работе с курсами валют, когда на каждую дату отчета отображается актуальное на тот момент значение, даже если оно было установлено давно.

Способ 3: Оптимизация архитектуры регистра (Рекомендуемый)

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

Рассмотрим, как изменить структуру регистра:

Выясним преимущества такого подхода:

  1. Простота запроса: Теперь не нужно использовать ОБЪЕДИНИТЬ ВСЕ. Запрос становится максимально простым: ВЫБРАТЬ * ИЗ РегистрСведений.Название.
  2. Масштабируемость: Если завтра появится "Ресурс 4", вам не придется менять конфигурацию, добавлять колонку в таблицу и переписывать запрос в СКД. Достаточно добавить новый элемент в перечисление/справочник.
  3. Гибкость в СКД: Пользователь сам сможет решать, что выводить в строки, а что в колонки, просто перетаскивая поле ТипПоказателя в настройках отчета.

Посмотрим на пример того, как лаконично выглядит настройка такого отчета в СКД: в строках мы просто группируем данные по ТипПоказателя и Номенклатура, а ресурс Значение выводим в область данных.

Резюме

Выбор метода зависит от ваших возможностей по изменению системы. Если регистр "чужой" или типовой — используйте Способ 1 с объединением выборок. Если же вы проектируете систему с нуля, крайне рекомендуем Способ 3, так как он соответствует принципам нормализации баз данных и значительно облегчает жизнь разработчику отчетов в будущем.

← На главную