При разработке аналитических отчетов в 1С часто возникает задача сравнения показателей текущего периода с аналогичными показателями прошлого года или любого другого произвольного интервала. Например, нам нужно вывести в одну строку остатки на текущую дату и остатки на конец декабря прошлого года, а также рассчитать средние продажи за эти периоды. Рассмотрим, как реализовать это в Системе компоновки данных (СКД) максимально эффективно.
Предположим, нам необходимо получить данные по товарам за два периода:
НачалоПериода_2021 и КонецПериода_2021).НачалоПериода_2022 и КонецПериода_2022).Стандартные механизмы СКД обычно предлагают два глобальных параметра: НачалоПериода и КонецПериода. Однако для нашей задачи их недостаточно, так как нам нужно одновременно работать с четырьмя разными границами времени. Проанализируем основные способы решения этой задачи.
Это самый «чистый» и профессиональный метод в СКД. Вместо того чтобы пытаться уместить все данные в один сложный запрос, мы создадим два отдельных набора данных-запроса, а затем свяжем их.
Шаг 1: Создание первого набора данных (2021 год)
Создадим набор данных НаборДанных2021. В тексте запроса обратимся к виртуальной таблице ОстаткиИОбороты, явно указав наши параметры в скобках:
ВЫБРАТЬ
Остатки.Товар КАК Товар,
Остатки.Склад КАК Склад,
Остатки.КонечныйОстаток КАК Остаток2021,
Остатки.Расход КАК Продажи2021
ИЗ
РегистрНакопления.Остатки.ОстаткиИОбороты(&НачалоПериода_2021, &КонецПериода_2021, , , ) КАК Остатки
Шаг 2: Создание второго набора данных (2022 год)
Создадим НаборДанных2022 аналогичным образом, отладив запрос через консоль запросов УФ:
ВЫБРАТЬ
Остатки.Товар КАК Товар,
Остатки.Склад КАК Склад,
Остатки.КонечныйОстаток КАК Остаток2022,
Остатки.Расход КАК Продажи2022
ИЗ
РегистрНакопления.Остатки.ОстаткиИОбороты(&НачалоПериода_2022, &КонецПериода_2022, , , ) КАК Остатки
Шаг 3: Настройка связей наборов данных
Перейдем на закладку «Связи наборов данных». Укажем НаборДанных2022 как основной, а НаборДанных2021 как подчиненный. Свяжем их по полям Товар и Склад. Это позволит СКД вывести данные за оба года в одну строку для каждого товара.
Если нам необходимо получить данные одним запросом, мы можем использовать конструкцию ОБЪЕДИНИТЬ ВСЕ.
ВЫБРАТЬ
Остатки.Товар КАК Товар,
Остатки.Склад КАК Склад,
Остатки.КонечныйОстаток КАК Остаток2021,
0 КАК Остаток2022,
Остатки.Расход КАК Продажи2021,
0 КАК Продажи2022
ИЗ
РегистрНакопления.Остатки.ОстаткиИОбороты(&НачалоПериода_2021, &КонецПериода_2021, , , ) КАК Остатки
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Остатки.Товар,
Остатки.Склад,
0,
Остатки.КонечныйОстаток,
0,
Остатки.Расход
ИЗ
РегистрНакопления.Остатки.ОстаткиИОбороты(&НачалоПериода_2022, &КонецПериода_2022, , , ) КАК Остатки
При таком подходе в ресурсах СКД необходимо указать функцию СУММА() для всех полей остатков и продаж. Система сама «схлопнет» строки по товару и складу, заполнив соответствующие колонки за разные годы.
Зачастую пользователю не нужно видеть промежуточные данные (например, продажи за прошлый год), но они необходимы для вычисления среднего значения или отклонения. Выясним, как это реализовать.
1. Вычисляемые поля:
На закладке «Вычисляемые поля» мы можем добавить поле СредниеПродажи. Формула может выглядеть так:
(Продажи2021 + Продажи2022) / 2
Или, если нужно среднее в день за конкретный период:
Продажи2021 / (РазностьДат(&НачалоПериода_2021, &КонецПериода_2021, "ДЕНЬ") + 1)
2. Скрытие полей от пользователя:
Чтобы поле Продажи2021 участвовало в расчетах, но не мозолило глаза пользователю в списке доступных полей, проанализируем настройки на закладке «Наборы данных». В колонке «Ограничение поля» (пиктограмма с перечеркнутым полем) установите галочки для «Поля выбора». Теперь поле нельзя выбрать в отчет, но СКД подтянет его из базы для расчета СреднихПродаж.
Также можно использовать «Условное оформление», установив видимость в значение Ложь или задав ширину колонки равную 0, но первый способ более надежен технически.
Если к остаткам нужно добавить цену на конкретный период, важно помнить, что виртуальная таблица СрезПоследних также принимает параметр даты. Проанализируем ситуацию: если мы делаем левое соединение с ценами внутри объединенного запроса, нам нужно передавать разные даты среза для каждой части объединения.
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&КонецПериода_2021, ) КАК Цены2021
ПО Остатки.Товар = Цены2021.Номенклатура
При работе с большими объемами данных рассмотрим использование временных таблиц:
ВТ_Товары.Резюме: Для получения средних продаж и остатков за прошлые месяцы оптимально использовать либо связи наборов данных (для простоты настройки), либо ручное управление параметрами виртуальных таблиц в фигурных скобках {} внутри одного запроса. Это дает полный контроль над данными, которые видит пользователь, и позволяет строить сложные сопоставительные отчеты.