Сравнение показателей текущего периода с аналогичным периодом прошлого года (анализ Year-over-Year) — одна из наиболее востребованных задач в управленческом учете и торговой аналитике. Несмотря на кажущуюся простоту реализации в табличных редакторах, в 1С эта задача требует понимания работы механизмов компоновки данных и построения запросов. В данной статье мы разберем, как объединить данные из разных временных отрезков в одну структуру и корректно сопоставить их по неделям.
Для того чтобы вывести данные за два разных периода в одной строке, разделенной по колонкам, мы не можем просто выбрать данные из базы. Нам необходимо применить механизм ОБЪЕДИНИТЬ ВСЕ (UNION ALL) в тексте запроса. Основная идея заключается в том, чтобы привести данные за прошлый год и текущий год к единому набору полей, где показатели будут разнесены по разным ресурсам.
Рассмотрим примерную структуру запроса. Мы создаем две выборки: одна для текущего года, вторая — для прошлого. В каждой выборке мы создаем колонки для обоих показателей, но заполняем их выборочно.
ВЫБРАТЬ
НЕДЕЛЯ(Продажи.Период) КАК НомерНедели,
Продажи.СуммаОборот КАК СуммаТекущийГод,
0 КАК СуммаПрошлыйГод
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериодаТекущий, &КонецПериодаТекущий, Неделя, ) КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
НЕДЕЛЯ(ПродажиПрошлогоГода.Период) КАК НомерНедели,
0,
ПродажиПрошлогоГода.СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериодаПрошлый, &КонецПериодаПрошлый, Неделя, ) КАК ПродажиПрошлогоГода
Проанализируем этот код: в первой части запроса мы получаем данные за текущий год и записываем сумму в колонку СуммаТекущийГод, оставляя СуммаПрошлыйГод пустой (равной нулю). Во второй части делаем наоборот. После этого результат объединения необходимо сгруппировать по полю НомерНедели, просуммировав ресурсы.
Использование встроенной функции НЕДЕЛЯ() в языке запросов 1С — самый быстрый способ получить номер недели от начала года. Однако здесь кроется важный нюанс: вычисление номера недели зависит от региональных настроек сервера и того, на какой день недели пришлось 1 января. Выясним причину возможного рассогласования: если в текущем году 1 января — это понедельник, а в прошлом — четверг, порядковые номера недель могут сместиться относительно рабочих дней.
Для более точного сопоставления профессионалы рекомендуют использовать приведение всех дат к началу недели через функцию НАЧАЛОПЕРИОДА(Дата, НЕДЕЛЯ) или использовать специализированные производственные календари. Если же допустима стандартная логика 1С, то группировка по номеру недели будет выглядеть так:
ВЫБРАТЬ
Т.НомерНедели КАК Неделя,
СУММА(Т.СуммаТекущийГод) КАК СуммаТекущая,
СУММА(Т.СуммаПрошлыйГод) КАК СуммаПрошлая
ИЗ
(ВложенныйЗапросСОбъединением) КАК Т
СГРУППИРОВАТЬ ПО
Т.НомерНедели
Если мы используем СКД, задачу можно решить еще элегантнее. Рассмотрим метод «смещения периода». Мы можем в наборе данных для прошлого года виртуально «прибавить» один год к дате продажи, чтобы система считала, что эти данные относятся к тому же временному интервалу, что и текущие продажи. Это позволит СКД автоматически соединить записи по полю Период.
Для настройки визуальной части отчета, чтобы он напоминал привычный Excel, выполним следующие шаги в настройках СКД:
НомерНедели.Период или оставить их статичными, если мы выводим показатели «Текущий» и «Прошлый» как отдельные ресурсы.СуммаТекущая и СуммаПрошлая.Разберем ситуацию, когда в одном году 52 недели, а в другом — 53. Это происходит из-за особенностей календаря. Если просто сопоставлять данные по номеру недели, то 53-я неделя текущего года останется без пары из прошлого года. Чтобы отчет не выглядел «рваным», можно использовать алгоритмы сглаживания или привязывать данные к «ретейл-календарю» (4-4-5), где количество недель в месяцах и годах строго фиксировано. В простых случаях достаточно функции ЕСТЬNULL(), чтобы вместо пустых значений на 53-й неделе выводился ноль.
Когда данных в регистрах очень много, прямое объединение в одном запросе может привести к замедлению работы. Посмотрим на пример оптимизации через временные таблицы:
ВТ_ТекущиеДанные.ВТ_ПрошлыеДанные.НомерНедели.Такой подход позволяет СУБД быстрее обрабатывать индексы и сокращает время ожидания формирования отчета пользователем.
Проанализируем, как добавить в отчет динамику изменений. Простого вывода двух колонок часто недостаточно. Нам нужно знать процент роста или падения. В СКД на закладке "Вычисляемые поля" мы можем добавить поле ПроцентОтклонения.
Важно помнить о защите от деления на ноль. Используем следующую формулу:
(ЕСТЬNULL(СуммаТекущая, 0) - ЕСТЬNULL(СуммаПрошлая, 0)) / ВЫБОР КОГДА ЕСТЬNULL(СуммаПрошлая, 0) = 0 ТОГДА 1 ИНАЧЕ СуммаПрошлая КОНЕЦ * 100
Это обеспечит корректное отображение данных, даже если в прошлом году продаж в эту конкретную неделю не было вовсе.
Таким образом, комбинируя механизмы объединения запросов, работу с временными таблицами и возможности оформления СКД, мы получаем мощный инструмент для сопоставительного анализа, который превосходит возможности Excel по скорости обработки больших массивов данных 1С.