Как в отчете СКД вывести данные за прошлый месяц в отдельной колонке?

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

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

На первый взгляд, может показаться, что это можно сделать с помощью простого вычисляемого поля, но это не так. СКД формирует набор данных строго за указанный период. Данные за другой период — это, по сути, результат другого запроса. Следовательно, чтобы их объединить в одном отчете, нужно использовать более сложные механизмы. Рассмотрим три основных способа решения этой задачи.

Способ 1: Использование двух наборов данных (классический подход)

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

Разберем реализацию по шагам.

  1. Создаем основной набор данных.
    В схеме компоновки данных добавим первый набор данных-запрос. Он будет получать информацию за основной период, который пользователь указывает в параметрах отчета. Назовем эти параметры стандартно: &НачалоПериода и &КонецПериода.
  2. Создаем второй набор данных для прошлого периода.
    Теперь добавим второй набор данных-запрос. Он должен быть практически полной копией первого. Единственное отличие будет в параметрах периода, которые он использует. Чтобы не путаться, создадим для него отдельные параметры в СКД, например, &НачалоПрошлогоПериода и &КонецПрошлогоПериода. В условиях виртуальной таблицы этого запроса будем использовать именно их.
  3. Настраиваем вычисление параметров прошлого периода.
    Перейдем на вкладку "Параметры" в конструкторе схемы компоновки данных. Здесь мы видим все четыре параметра: два для основного периода и два для прошлого. Для параметров &НачалоПериода и &КонецПериода пользователь будет вводить значения вручную. А вот для &НачалоПрошлогоПериода и &КонецПрошлогоПериода нам нужно настроить автоматическое вычисление на основе основного периода. Для этого в колонке "Выражение" пропишем формулы с использованием встроенной функции языка 1С ДОБАВИТЬКДАТЕ().
    • Для параметра &НачалоПрошлогоПериода выражение будет: ДОБАВИТЬКДАТЕ(&НачалоПериода, "МЕСЯЦ", -1)
    • Для параметра &КонецПрошлогоПериода выражение будет: ДОБАВИТЬКДАТЕ(&КонецПериода, "МЕСЯЦ", -1)

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

  4. Связываем наборы данных.
    Самый важный шаг. Переходим на вкладку "Связи наборов данных". Здесь нужно указать СКД, как сопоставлять строки из первого и второго наборов.
    • В качестве источника связи выбираем наш основной набор данных.
    • В качестве приемника связи — набор данных за прошлый период.
    • Устанавливаем связь по всем ключевым измерениям (разрезам аналитики), по которым мы хотим сопоставлять данные. Например, Контрагент, Договор, Номенклатура и т.д. Выражение связи будет выглядеть как Источник.Контрагент = Приемник.Контрагент.
    • Важный момент: тип связи нужно установить как Левое соединение. Это гарантирует, что в отчет попадут все записи из основного периода, даже если для них не нашлось данных в прошлом периоде. В этом случае поля из второго набора будут просто пустыми (NULL).
  5. Выводим поля в отчет.
    После настройки связи все поля из второго набора данных (например, СуммаОборотПрошлыйМесяц) становятся доступны на вкладке "Настройки" наравне с полями основного набора. Теперь их можно перетащить в структуру отчета и использовать для вывода или в вычисляемых полях для расчета отклонений.

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

Способ 2: Объединение данных внутри одного запроса

Этот метод идеологически похож на первый, но вся работа по объединению данных происходит не средствами СКД, а на уровне одного-единственного запроса с использованием ЛЕВОЕ СОЕДИНЕНИЕ.

Суть подхода: мы пишем запрос, в котором основная выборка (данные за текущий период) соединяется сама с собой (но уже с данными за прошлый период) по ключевым полям аналитики. Это может быть более производительно, если соединение происходит по небольшому числу индексированных полей.

Как и в первом способе, нам понадобятся четыре параметра периода: &НачалоПериода, &КонецПериода, &НачалоПрошлогоПериода и &КонецПрошлогоПериода. Последние два также настраиваются через выражение с ДОБАВИТЬКДАТЕ().

Посмотрим на примерный текст запроса для одного набора данных:


ВЫБРАТЬ
    ТекущийПериод.Контрагент,
    ТекущийПериод.СуммаОборот КАК СуммаЗаТекущийПериод,
    ЕСТЬNULL(ПрошлыйПериод.СуммаОборот, 0) КАК СуммаЗаПрошлыйПериод
ИЗ
    РегистрНакопления.Взаиморасчеты.Обороты(&НачалоПериода, &КонецПериода, ,) КАК ТекущийПериод
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Взаиморасчеты.Обороты(&НачалоПрошлогоПериода, &КонецПрошлогоПериода, ,) КАК ПрошлыйПериод
        ПО ТекущийПериод.Контрагент = ПрошлыйПериод.Контрагент

Проанализируем этот запрос:

В результате этот запрос сразу вернет таблицу, где в одной строке будут данные и по текущему, и по прошлому периоду. Дальнейшая настройка отчета в СКД будет стандартной.

Способ 3: Использование функции `ВычислитьВыражение()` (продвинутый)

Это самый мощный, но и самый сложный в настройке метод. Функция ВычислитьВыражение() — это инструмент языка выражений СКД. Она не получает новые данные из базы, а работает с теми данными, которые уже были получены запросом. Ее основная сила — возможность обращаться к значениям показателей в других группировках отчета (например, в родительской, дочерней или соседней).

Чтобы этот метод сработал, нам нужно подготовить данные особым образом.

Разберем по шагам.

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

    В результате мы получим таблицу, где для каждого контрагента будет две строки: одна для прошлого периода, другая для текущего. Поле ПорядокПериода нужно для правильной сортировки.

  2. Настраиваем структуру отчета.
    На вкладке "Настройки" создаем структуру. Сначала идет группировка по основным измерениям (например, Контрагент). Внутрь этой группировки вкладываем группировку по нашему полю ПредставлениеПериода. Для этой вложенной группировки нужно настроить сортировку по полю ПорядокПериода по возрастанию. В итоге отчет будет выглядеть так:

    Контрагент "Ромашка"
        Прошлый период    1000
        Текущий период    1500

  3. Применяем ВычислитьВыражение().
    Теперь самое интересное. Мы хотим, чтобы в строке "Текущий период" была колонка с данными из строки "Прошлый период". Создадим вычисляемое поле, например, СуммаПрошлыйПериод, с выражением: ВычислитьВыражение("Сумма(СуммаОборот)", "Группировка", "Предыдущая")

    Разберем это выражение:

    • "Сумма(СуммаОборот)" — первый параметр. Это строковое представление выражения, значение которого мы хотим получить.
    • "Группировка" — второй параметр. Указывает, что вычисление нужно проводить в контексте группировок.
    • "Предыдущая" — третий параметр. Указывает, что нам нужно значение из предыдущей по порядку группировки на том же уровне.

    Это выражение, будучи вычисленным в строке "Текущий период", "заглянет" в предыдущую строку ("Прошлый период") и возьмет оттуда итоговое значение ресурса Сумма(СуммаОборот). Чтобы это поле не выводилось для строки "Прошлый период", можно задать условное оформление или использовать выражение вида ВЫБОР КОГДА ПредставлениеПериода = "Текущий период" ТОГДА ... ИНАЧЕ 0 КОНЕЦ.

Этот метод сложнее в настройке, но он незаменим для более сложных отчетов, где нужно считать скользящие средние, процент роста от предыдущего периода и другие подобные показатели, работающие со "соседними" данными. Для практики построения таких отчетов подойдут примеры реализации отчетов со сложными выражениями в СКД.

← На главную