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