При разработке отчетов в Системе компоновки данных (СКД) часто возникает задача сравнения показателей за два разных периода (например, продажи текущего месяца в сравнении с аналогичным месяцем прошлого года). Несмотря на кажущуюся простоту — добавить два набора данных или объединить запросы с разными параметрами — разработчики часто сталкиваются с тем, что система игнорирует разные даты и выводит одни и те же данные для обоих периодов.
В этой статье мы подробно разберем, почему так происходит, как работает механизм автозаполнения СКД и какими способами можно реализовать корректное сравнение периодов.
Рассмотрим ситуацию: вы создаете запрос к виртуальной таблице оборотов и пытаетесь передать туда две пары параметров. В тексте запроса это выглядит примерно так:
ВЫБРАТЬ ...
ИЗ РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачалоПериода1, &КонецПериода1, , )
...
ОБЪЕДИНИТЬ ВСЕ
...
ИЗ РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачалоПериода2, &КонецПериода2, , )
Проблема заключается в том, что в СКД по умолчанию включено Автозаполнение. Система компоновки данных обладает «интеллектом»: когда она видит обращение к виртуальным таблицам (остатки, обороты), она автоматически ищет в схеме параметры с именами НачалоПериода и КонецПериода.
Если такие параметры существуют (а они часто создаются автоматически), СКД «насильно» подставляет их значения во все виртуальные таблицы запроса, игнорируя те имена переменных, которые вы прописали вручную в скобках. В итоге, какие бы разные даты вы ни ставили в НачалоПериода2, система все равно подставит туда значения из основных параметров периода.
Самый простой и быстрый способ решить проблему — полностью отказаться от использования зарезервированных имен НачалоПериода и КонецПериода. Проанализируем, как должен выглядеть исправленный запрос.
Шаги для реализации:
Пример корректного запроса с использованием ОБЪЕДИНИТЬ ВСЕ:
ВЫБРАТЬ
Продажи.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
Продажи.КоличествоОборот КАК Количество1,
0 КАК Количество2
ИЗ
РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&Начало1, &Конец1, , ) КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Продажи.АналитикаУчетаНоменклатуры.Номенклатура,
0,
Продажи.КоличествоОборот
ИЗ
РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&Начало2, &Конец2, , ) КАК Продажи
Используя имена Начало1, Конец1, Начало2 и Конец2, мы «обманываем» механизм автозаполнения, и он перестает принудительно связывать таблицы с глобальными настройками периода.
Если вы хотите полного контроля над запросом, можно отключить свойство Автозаполнение в настройках набора данных (флажок в верхней части окна конструктора схемы компоновки). Однако помните: при отключении автозаполнения вам придется вручную указать все доступные поля, условия и параметры на соответствующих вкладках СКД. Это трудоемкий процесс, но он гарантирует, что НачалоПериода и КонецПериода будут работать именно так, как вы указали в коде.
Заставлять пользователя вводить четыре отдельные даты неудобно. Проанализируем, как сделать интерфейс профессиональным. Вместо четырех параметров типа Дата, создадим два параметра с типом СтандартныйПериод:
ПериодСравнения1ПериодСравнения2Для технических параметров запроса (Начало1, Конец1 и т.д.), которые мы создали в Решении №1, установим ограничение доступности (галочка «Ограничение доступности»), чтобы пользователь их не видел. В поле Выражение для них пропишем:
Начало1: &ПериодСравнения1.ДатаНачалаКонец1: &ПериодСравнения1.ДатаОкончанияНачало2: &ПериодСравнения2.ДатаНачалаКонец2: &ПериодСравнения2.ДатаОкончанияТеперь пользователь выбирает привычные интервалы (например, «Этот месяц» и «Прошлый месяц»), а СКД автоматически передает правильные границы дат в виртуальные таблицы.
Разберем типичную ошибку при соединении периодов. Часто разработчики используют ВНУТРЕННЕЕ СОЕДИНЕНИЕ (INNER JOIN) для объединения данных двух периодов. Рассмотрим, к чему это приведет:
Если товар продавался в первом периоде, но не продавался во втором, он вообще не попадет в отчет.
Правильный алгоритм действий:
ОБЪЕДИНИТЬ ВСЕ, как показано в примере выше. Это самый производительный метод. После объединения СКД сама сгруппирует данные по номенклатуре (если настроены соответствующие ресурсы).ПОЛНОЕ СОЕДИНЕНИЕ.ЕСТЬNULL для полей с числами, чтобы избежать пустых значений в итоговых колонках.Рассмотрим пример правильного вывода отклонений через Вычисляемые поля. Не считайте разницу между периодами в самом запросе. Лучше добавьте вычисляемое поле на закладке «Вычисляемые поля» с выражением Количество2 - Количество1. Это позволит системе корректно рассчитывать итоги по группировкам и общие итоги отчета.
Подводя итог, можно сказать, что работа с двумя периодами в СКД требует понимания того, как платформа управляет виртуальными таблицами. Использование уникальных имен параметров в сочетании с типом СтандартныйПериод — это наиболее надежный и удобный способ реализации подобных отчетов.