При построении отчетов или обработке данных в 1С часто возникает задача: имея список документов или записей регистра с датами изменения цен, необходимо вычислить «интервалы жизни» каждой конкретной цены. Например, если цена на товар менялась 1-го, 6-го и 15-го числа, нам нужно получить диапазоны: с 1-го по 5-е, с 6-го по 14-е и с 15-го по 31-е число. Рассмотрим, как решить эту задачу максимально эффективно.
Если данные в вашей исходной таблице (временной или постоянной) уже содержат даты начала действия цен, самый простой способ — это использование агрегатных функций МИНИМУМ() и МАКСИМУМ() по сгруппированным данным. Однако важно помнить: этот метод корректно работает только в том случае, если вы сгруппировали данные так, чтобы в одну группу попадали строго строки с одинаковой ценой, идущие подряд.
Рассмотрим пример построения запроса:
ВЫБРАТЬ
Т.Номенклатура,
Т.Цена,
МИНИМУМ(Т.Период) КАК НачалоПериода,
МАКСИМУМ(Т.Период) КАК КонецПериода
ИЗ
ВТ_Цены КАК Т
СГРУППИРОВАТЬ ПО
Т.Номенклатура,
Т.Цена
Важное примечание: Этот метод вернет только «минимальную» и «максимальную» даты из исходного набора. Если одна и та же цена встречается для номенклатуры в разные периоды, разделенные другой ценой, обычная группировка объединит их в один интервал. Для более точного расчета необходимо использовать дополнительные алгоритмы.
В случаях, когда данные сложны и требуют логики «соседних строк» (чтобы определить дату окончания текущей цены по дате начала следующей), оптимальным решением является выгрузка результата запроса в ТаблицаЗначений. Это позволяет избежать сверхсложных соединений внутри языка запросов, которые могут сильно замедлить систему при больших объемах данных.
Разберем алгоритм по шагам:
РегистрСведений.ЦеныНоменклатуры или Документ.ПоступлениеТоваровУслуг, сортируя результат по Номенклатура и Период.Выгрузить().ТекущаяСтрока.Номенклатура совпадает с ПредыдущаяСтрока.Номенклатура, то мы устанавливаем ПредыдущаяСтрока.ДатаОкончания = ТекущаяСтрока.ДатаНачала - 1.Этот подход позволяет гибко обрабатывать любые сценарии, включая разрывы в датах или возврат к старым ценам.
Если вам необходимо оставаться строго в рамках запроса, можно реализовать подход с «искусственным» расширением интервалов. Вы можете получить таблицу всех дат изменений цен, а затем через ЛЕВОЕ СОЕДИНЕНИЕ сопоставить каждую дату с «ближайшей следующей датой» для той же номенклатуры.
Порядок действий:
ВТ_ДатыЦен, содержащую только Номенклатура, Цена и Период.Т1.Номенклатура = Т2.Номенклатура И Т2.Период > Т1.Период.КонецПериода как МИНИМУМ(Т2.Период) минус 1 секунда.Такой метод позволяет получить четкие интервалы без необходимости выгрузки в ТаблицаЗначений, но требует осторожности при работе с очень большими выборками, так как соединение таблицы самой с собой может существенно нагрузить базу данных.
Для решения задачи определения периодов цен мы рекомендуем комбинированный подход: используйте Запрос для получения «сырых» данных о датах и ценах, а для финальной подготовки отчетных интервалов — обработку в ТаблицаЗначений. Это обеспечит высокую производительность и позволит легко отлаживать логику формирования интервалов.