При анализе эффективности розничной точки часто возникает задача расчета средней выручки за день. Основная сложность заключается в том, что календарное количество дней в месяце (30 или 31) далеко не всегда совпадает с фактическим количеством дней, когда магазин работал и совершал продажи. Более того, в течение одного рабочего дня может быть создано несколько документов ОтчетОРозничныхПродажах (например, при смене кассиров или закрытии нескольких смен), что делает простой подсчет количества документов некорректным.
В данной статье мы разберем, как правильно вычислить количество уникальных дней с помощью языка запросов 1С, рассмотрим более оптимальные способы через регистры накопления и узнаем, как автоматизировать этот процесс в Системе компоновки данных (СКД).
Если мы работаем напрямую с документами, нам необходимо решить две задачи: убрать время из даты документа (привести её к началу дня) и исключить повторения, если за один день было создано два и более отчета. Проанализируем наиболее эффективную конструкцию запроса.
Для решения задачи мы будем использовать функцию НАЧАЛОПЕРИОДА, которая «отсекает» время, оставляя только дату, и агрегатную функцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...), которая посчитает только уникальные значения дат.
Рассмотрим пример кода запроса:
ВЫБРАТЬ
СУММА(Отчет.СуммаДокумента) КАК ОбщаяВыручка,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ НАЧАЛОПЕРИОДА(Отчет.Дата, ДЕНЬ)) КАК КоличествоТорговыхДней
ИЗ
Документ.ОтчетОРозничныхПродажах КАК Отчет
ГДЕ
Отчет.Проведен = ИСТИНА
И Отчет.Дата МЕЖДУ &НачалоПериода И &КонецПериода
Разберем подробнее, что происходит в этом запросе:
НАЧАЛОПЕРИОДА(Отчет.Дата, ДЕНЬ) — эта функция критически важна. Если её не использовать, система будет считать уникальной каждую секунду времени. Так как документы создаются в разное время, КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) просто вернет общее число документов. Приведение к началу дня превращает, например, «01.10.2023 14:30:00» и «01.10.2023 18:00:00» в одну и ту же дату — «01.10.2023 00:00:00».РАЗЛИЧНЫЕ — это ключевое слово внутри функции КОЛИЧЕСТВО гарантирует, что если у нас есть пять документов за одно число, в итоговый расчет попадет только единица.Отчет.Проведен = ИСТИНА, чтобы в статистику не попали черновики или помеченные на удаление объекты.В профессиональной разработке на платформе 1С (особенно в конфигурациях Управление торговлей 11, Далион или ERP) расчет выручки напрямую по документам считается плохим тоном. Это связано с низкой производительностью и риском не учесть корректировки. Правильнее обращаться к регистру накопления ВыручкаИСебестоимостьПродаж или Продажи.
Посмотрим на пример запроса к виртуальной таблице оборотов:
ВЫБРАТЬ
Продажи.Период КАК ДатаТорговли,
СУММА(Продажи.СуммаВыручкиОборот) КАК СуммаЗаДень
ПОМЕСТИТЬ ВТ_ПродажиПоДням
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, ДЕНЬ, ) КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Период
;
ВЫБРАТЬ
СУММА(СуммаЗаДень) КАК ИтогоВыручка,
КОЛИЧЕСТВО(*) КАК ВсегоДней,
СУММА(СуммаЗаДень) / КОЛИЧЕСТВО(*) КАК СредняяВыручка
ИЗ
ВТ_ПродажиПоДням
Выясним причину, почему этот способ лучше:
Обороты с периодичностью ДЕНЬ уже содержит сгруппированные данные. Базе данных не нужно сканировать тысячи документов.Если вы строите отчет в СКД, вам не обязательно прописывать сложные вычисления в самом тексте запроса. Платформа позволяет гибко настроить расчет ресурсов.
Рассмотрим по шагам, как это сделать:
Дата документа (или Период из регистра).Количество(Различные(НачалоПериода(Дата, "День"))).Если в вашем наборе данных (запросе) уже используется периодичность по дням, выражение ресурса упрощается до Количество(Дата) или Количество(Период). СКД автоматически применит группировку в зависимости от настроек отчета.
Проанализируем ситуацию, когда бизнес-требования могут отличаться. Существует два подхода к расчету средней выручки:
Для реализации второго варианта (календарные дни) в 1С используется функция РАЗНОСТЬДАТ. Пример выражения:
РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ) + 1
Обратите внимание на «+1» — это необходимо, так как РАЗНОСТЬДАТ считает количество переходов между датами, и для корректного включения обоих границ периода в расчет нужно добавлять единицу.
Использование конструкции КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) может быть ресурсоемким на очень больших объемах данных (миллионы строк чеков), так как SQL-серверу приходится строить временные индексы для поиска уникальных значений. Для ускорения работы мы рекомендуем использовать предварительную группировку во временных таблицах (как показано во втором способе). Это снижает нагрузку на сервер и делает отчеты более отзывчивыми для конечного пользователя.
Также важно учитывать возможность «пустых» дней. Если в системе создан документ, но в нем нет сумм (или только возвраты, которые обнулили выручку), запрос все равно посчитает этот день как торговый. Чтобы избежать искажения статистики, всегда добавляйте условие ГДЕ СуммаВыручки > 0.