Как в СКД вывести данные за два разных периода в одном отчете и избежать дублирования дат?

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

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

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

Разбор проблемы: почему параметры «схлопываются»?

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


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

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

Если такие параметры существуют (а они часто создаются автоматически), СКД «насильно» подставляет их значения во все виртуальные таблицы запроса, игнорируя те имена переменных, которые вы прописали вручную в скобках. В итоге, какие бы разные даты вы ни ставили в НачалоПериода2, система все равно подставит туда значения из основных параметров периода.

Решение №1: Использование уникальных имен параметров

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

Шаги для реализации:

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

Пример корректного запроса с использованием ОБЪЕДИНИТЬ ВСЕ:


ВЫБРАТЬ
    Продажи.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
    Продажи.КоличествоОборот КАК Количество1,
    0 КАК Количество2
ИЗ
    РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&Начало1, &Конец1, , ) КАК Продажи

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

ВЫБРАТЬ
    Продажи.АналитикаУчетаНоменклатуры.Номенклатура,
    0,
    Продажи.КоличествоОборот
ИЗ
    РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&Начало2, &Конец2, , ) КАК Продажи

Используя имена Начало1, Конец1, Начало2 и Конец2, мы «обманываем» механизм автозаполнения, и он перестает принудительно связывать таблицы с глобальными настройками периода.

Решение №2: Отключение автозаполнения

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

Решение №3: Оптимизация интерфейса через «СтандартныйПериод»

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

Для технических параметров запроса (Начало1, Конец1 и т.д.), которые мы создали в Решении №1, установим ограничение доступности (галочка «Ограничение доступности»), чтобы пользователь их не видел. В поле Выражение для них пропишем:

  1. Для Начало1: &ПериодСравнения1.ДатаНачала
  2. Для Конец1: &ПериодСравнения1.ДатаОкончания
  3. Для Начало2: &ПериодСравнения2.ДатаНачала
  4. Для Конец2: &ПериодСравнения2.ДатаОкончания

Теперь пользователь выбирает привычные интервалы (например, «Этот месяц» и «Прошлый месяц»), а СКД автоматически передает правильные границы дат в виртуальные таблицы.

Важные замечания по структуре запроса

Разберем типичную ошибку при соединении периодов. Часто разработчики используют ВНУТРЕННЕЕ СОЕДИНЕНИЕ (INNER JOIN) для объединения данных двух периодов. Рассмотрим, к чему это приведет:

Если товар продавался в первом периоде, но не продавался во втором, он вообще не попадет в отчет.

Правильный алгоритм действий:

  1. Используйте ОБЪЕДИНИТЬ ВСЕ, как показано в примере выше. Это самый производительный метод. После объединения СКД сама сгруппирует данные по номенклатуре (если настроены соответствующие ресурсы).
  2. Если вы все же предпочитаете соединения, используйте ПОЛНОЕ СОЕДИНЕНИЕ.
  3. При использовании соединений обязательно используйте функцию ЕСТЬNULL для полей с числами, чтобы избежать пустых значений в итоговых колонках.

Рассмотрим пример правильного вывода отклонений через Вычисляемые поля. Не считайте разницу между периодами в самом запросе. Лучше добавьте вычисляемое поле на закладке «Вычисляемые поля» с выражением Количество2 - Количество1. Это позволит системе корректно рассчитывать итоги по группировкам и общие итоги отчета.

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

← На главную