В процессе разработки отчетов в среде 1С:Предприятие программисты регулярно сталкиваются с необходимостью группировки данных по периодам. Платформа предоставляет отличные встроенные инструменты для работы со стандартным календарем, где неделя по умолчанию начинается в понедельник. Однако реальный бизнес живет по своим правилам. Финансовые недели, графики сменности, периоды поставок или маркетинговые акции часто требуют нестандартных рамок — например, когда неделя должна строго начинаться с четверга и заканчиваться в среду следующей недели.
В этой статье мы подробно разберем, как решить эту задачу на уровне запросов СУБД, механизмов Системы компоновки данных (СКД) и интерфейса пользователя. Мы проанализируем различные подходы — от изящных математических формул до надежных архитектурных решений с использованием вспомогательных таблиц.
Давайте разберем по шагам, как получить дату начала такой нестандартной недели прямо внутри запроса без использования тяжелых условий. Для этого мы применим комбинацию функций ДОБАВИТЬКДАТЕ и НАЧАЛОПЕРИОДА.
Идея заключается в том, чтобы временно «сдвинуть» анализируемую дату вперед на такое количество дней, чтобы четверг стал визуальным аналогом понедельника для стандартной функции НАЧАЛОПЕРИОДА, а затем вернуть результат обратно. Для недели, начинающейся с четверга, это смещение составляет ровно 4 дня.
Посмотрим на пример формулы, которую мы можем написать в тексте запроса:
ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(Продажи.Период, ДЕНЬ, 4), НЕДЕЛЯ), ДЕНЬ, -4) КАК НачалоНестандартнойНедели
Проанализируем ситуацию и детально разберем, как работает эта математическая модель на конкретных примерах дат:
27.10.2023 + 4 дня = 31.10.2023 (это вторник следующей календарной недели).НАЧАЛОПЕРИОДА(..., НЕДЕЛЯ): началом недели для вторника 31.10.2023 будет понедельник 30.10.2023.30.10.2023 - 4 дня = 26.10.2023 (четверг). Формула отработала абсолютно верно!01.11.2023 + 4 дня = 05.11.2023 (это воскресенье).30.10.2023.30.10.2023 - 4 дня = 26.10.2023 (четверг). Снова точный результат!02.11.2023 + 4 дня = 06.11.2023 (это понедельник новой календарной недели).06.11.2023.06.11.2023 - 4 дня = 02.11.2023 (четверг). Логика работает безупречно на любых стыках дат.Если математический метод кажется вам слишком абстрактным или его тяжело читать коллегам по разработке, мы можем воспользоваться более наглядной условной конструкцией в запросе. Для этого задействуем функцию ДЕНЬНЕДЕЛИ.
Логика нашего условия проста: если порядковый номер дня недели больше или равен 4 (то есть это четверг, пятница, суббота или воскресенье), то началом нашей производственной недели будет четверг текущей календарной недели. Если же день недели меньше 4 (понедельник, вторник, среда), то началом будет четверг предыдущей календарной недели.
Рассмотрим подробнее реализацию этого алгоритма в запросе:
ВЫБОР
КОГДА ДЕНЬНЕДЕЛИ(Продажи.Период) >= 4
ТОГДА ДОБАВИТЬКДАТЕ(Продажи.Период, ДЕНЬ, 4 - ДЕНЬНЕДЕЛИ(Продажи.Период))
ИНАЧЕ ДОБАВИТЬКДАТЕ(Продажи.Период, ДЕНЬ, -(ДЕНЬНЕДЕЛИ(Продажи.Период) + 3))
КОНЕЦ КАК НачалоНестандартнойНедели
Этот способ более многословен, но он наглядно показывает логику расчетов. Например, если функция ДЕНЬНЕДЕЛИ возвращает нам 2 (вторник), запрос пойдет по ветке ИНАЧЕ и вычтет из вторника 5 дней -(2 + 3) = -5, мгновенно перемещая нас на четверг прошлой недели.
Когда мы строим отчет на базе Системы компоновки данных (СКД), перегружать основной запрос к базе данных сложными математическими вычислениями дат не обязательно. Мы можем перенести эту логику на уровень вычисляемых полей компоновки.
Давайте настроим этот механизм по шагам:
ПроизводственнаяНеделя.Выражение для вычисляемого поля СКД будет выглядеть следующим образом:
ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(Период, "ДЕНЬ", 4), "НЕДЕЛЯ"), "ДЕНЬ", -4)
После добавления этого поля мы можем использовать его на вкладке Настройки в качестве поля группировки. СКД автоматически сгруппирует все наши детальные записи по рассчитанным четвергам.
Рассмотренные выше методы вычисления дат «на лету» отлично подходят для простых отчетов. Однако у них есть один фундаментальный недостаток — проблема дополнения периодов. Если в течение какой-то из наших нестандартных недель у компании не было продаж или движений по регистру, эта неделя просто выпадет из результирующей таблицы отчета. Стандартная системная функция дополнения периодов СКД не сможет восстановить пропущенные нестандартные недели, поскольку она ничего не знает о нашей логике сдвига.
Чтобы решить эту проблему профессионально, применим классический архитектурный подход с использованием вспомогательного календаря. Разберем этот алгоритм:
ДатаНачала (четверг) и ДатаОкончания (среда).
ЛЕВОЕ СОЕДИНЕНИЕ ВрТаблицаПериодов КАК Периоды
ПО Продажи.Период МЕЖДУ Периоды.ДатаНачала И Периоды.ДатаОкончания
Использование левого соединения гарантирует, что в финальном отчете будут выведены абсолютно все производственные недели из нашего календаря, даже если по ним не было зарегистрировано ни одного хозяйственного оборота. В полях показателей (например, сумма продаж) при этом будут выводиться пустые значения или нули.
С точки зрения юзабилити, стандартный диалог выбора периода 1С становится неудобным для пользователя, работающего по нестандартному календарю. Кнопки вроде «Текущая неделя» или «Предыдущая неделя» будут устанавливать границы с понедельника по воскресенье, что приведет к искажению данных в отчете.
Для создания комфортной рабочей среды пользователя мы можем применить следующий подход:
Рассмотрим пример кода на встроенном языке для расчета текущей производственной недели:
ТекущаяДата = ТекущаяДатаСеанса();
// Вычисляем начало текущей нестандартной недели
НачалоЭтойНедели = ДобавитьКДате(НачалоПериода(ДобавитьКДате(ТекущаяДата, "ДЕНЬ", 4), "НЕДЕЛЯ"), "ДЕНЬ", -4);
КонецЭтойНедели = КонецДня(ДобавитьКДате(НачалоЭтойНедели, "ДЕНЬ", 6));
Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоЭтойНедели);
Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецЭтойНедели);
Этот код гарантирует, что отчет пользователя всегда будет формироваться строго в границах бизнес-логики компании.
Мы рассмотрели несколько эффективных способов реализации нестандартных еженедельных периодов в системе 1С:Предприятие. Математический метод смещения дат через ДОБАВИТЬКДАТЕ идеален для быстрого решения задач «на лету» в консоли запросов. Метод с использованием ВЫБОР КОГДА обеспечивает отличную читаемость кода. Применение вычисляемых полей СКД позволяет гибко управлять группировками в интерфейсе отчетов, а связывание со вспомогательной таблицей периодов является самым надежным архитектурным решением, гарантирующим вывод пустых периодов без потери данных.