Как получить срез последних записей регистра сведений, игнорируя часть измерений?

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

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

Почему не работает стандартный подход

Виртуальная таблица СрезПоследних возвращает данные в разрезе уникальных комбинаций всех измерений. Если в вашем регистре есть измерения Товар и ЕдИзм, система вернет запись для каждого сочетания товара и упаковки. Если задача состоит в том, чтобы «свернуть» регистр только по товару и взять актуальную цену, независимо от того, в какой упаковке она была установлена, нам нужно самостоятельно определить координаты записи с максимальным периодом.

Решение задачи с помощью пакетного запроса

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

Шаг 1: Определение «координат» последних записей.

В первом пакете нашего запроса мы должны выбрать только нужные нам измерения (в нашем случае это Товар) и вычислить для них максимальный период. Если записей с одинаковым периодом несколько, необходимо также учитывать регистратор (или иные поля, определяющие последовательность внутри секунды).


ВЫБРАТЬ
    Регистр.Товар КАК Товар,
    МАКСИМУМ(Регистр.Период) КАК Период,
    МАКСИМУМ(Регистр.Регистратор) КАК Регистратор
ПОМЕСТИТЬ ВТ_Координаты
ИЗ
    РегистрСведений.ЦеныТоваров КАК Регистр
СГРУППИРОВАТЬ ПО
    Регистр.Товар

Шаг 2: Получение полных данных через соединение.

Теперь, имея временную таблицу ВТ_Координаты, мы можем соединить её с исходной физической таблицей регистра. Это позволит нам вытянуть значения ресурсов (например, цену) для тех строк, которые мы определили как самые «свежие» для каждого товара.


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

Почему этот метод эффективен

  1. Гибкость: Мы не ограничены структурой измерений регистра и можем манипулировать данными по любому подмножеству полей.
  2. Производительность: Использование временных таблиц позволяет системе оптимизировать план выполнения запроса, что крайне важно для больших объемов данных.
  3. Точность: Использование МАКСИМУМ(Регистратор) позволяет однозначно разрешить коллизии в рамках одной секунды, что является критически важным для корректного среза.

Альтернативные подходы

Если запрос получается слишком сложным, некоторые разработчики прибегают к использованию конструкции ВЫБРАТЬ ПЕРВЫЕ 1 внутри коррелированного подзапроса, однако такой метод может негативно сказаться на производительности при большом количестве номенклатуры. Метод с использованием временных таблиц остается наиболее «чистым» и предпочтительным с точки зрения архитектуры 1С:Предприятия.

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

← На главную