Как получить актуальную цену из непериодического регистра сведений на произвольную дату?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

Часто в практике разработки на 1С возникает задача сопоставить данные из двух разных регистров. Например, у нас есть регистр с данными о продажах (количество товара на определенную дату) и регистр с ценами, который не является периодическим, а просто хранит историю изменения цен в разрезе дат. Возникает вопрос: как при выборке количества товаров «подтянуть» именно ту цену, которая действовала на этот момент?

Рассмотрим пошагово, как решить эту задачу с помощью механизмов запросов 1С.

Основные подходы к решению

Для решения задачи, когда даты в двух регистрах не совпадают, мы не можем использовать простое соединение по равенству полей Дата. Нам нужно найти такое значение, которое было актуальным на конкретный момент времени из первого регистра. Разберем самый распространенный алгоритм, основанный на использовании временных таблиц и соединения по условию неравенства.

Алгоритм решения через временные таблицы

Для того чтобы запрос работал корректно и был производительным, рекомендуется разбить процесс на несколько этапов с использованием пакета запросов.

  1. Получение пар данных: Сначала нам необходимо соединить оба регистра по Номенклатуре. При этом условием соединения должно быть ДатаРегистраЦен <= ДатаРегистраКоличества. Таким образом, мы получим все возможные цены, которые были установлены до момента продажи или в момент продажи.
  2. Определение актуальной цены: Так как после первого шага у нас получится множество записей (все цены, которые когда-либо действовали до указанной даты), нам нужно выбрать только самую позднюю из них. Для этого мы сворачиваем полученную таблицу по Номенклатуре, Количеству и ДатаКоличества, используя агрегатную функцию МАКСИМУМ(ДатаЦены).
  3. Финальное соединение: Имея на руках таблицу, где каждой строке с продажей сопоставлена максимальная подходящая дата цены, мы делаем финальное соединение с физической таблицей регистра цен по полям Номенклатура и ДатаЦены. Это позволит нам получить конкретное значение Цена.

Пример реализации запроса

Посмотрим, как это может выглядеть в коде 1С:


ВЫБРАТЬ
    РегистрКоличества.Номенклатура КАК Номенклатура,
    РегистрКоличества.Дата КАК Дата,
    РегистрКоличества.Количество КАК Количество,
    РегистрЦен.Дата КАК ДатаЦены
ПОМЕСТИТЬ ВТ_Соединение
ИЗ
    РегистрСведений.КоличествоТоваров КАК РегистрКоличества
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныТоваров КАК РегистрЦен
    ПО РегистрКоличества.Номенклатура = РегистрЦен.Номенклатура
    И РегистрКоличества.Дата >= РегистрЦен.Дата
;

ВЫБРАТЬ
    ВТ.Номенклатура,
    ВТ.Дата,
    ВТ.Количество,
    МАКСИМУМ(ВТ.ДатаЦены) КАК МаксДатаЦены
ПОМЕСТИТЬ ВТ_МаксЦены
ИЗ
    ВТ_Соединение КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Номенклатура, ВТ.Дата, ВТ.Количество
;

ВЫБРАТЬ
    ВТ_МаксЦены.Номенклатура,
    ВТ_МаксЦены.Дата,
    ВТ_МаксЦены.Количество,
    РегистрЦен.Цена
ИЗ
    ВТ_МаксЦены КАК ВТ_МаксЦены
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныТоваров КАК РегистрЦен
    ПО ВТ_МаксЦены.Номенклатура = РегистрЦен.Номенклатура
    И ВТ_МаксЦены.МаксДатаЦены = РегистрЦен.Дата

О чем важно помнить при работе с датами

При использовании данного метода крайне важно обращать внимание на формат хранения даты в регистрах:

Использование этого подхода позволит вам точно определять состояние системы на любую заданную дату, даже если данные хранятся в обычных непериодических регистрах сведений.

← На главную