Что такое СрезПервых и СрезПоследних в регистрах сведений 1С и чем они отличаются?

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

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

Базовые понятия: СрезПоследних и СрезПервых

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

  1. СрезПоследних — получает наиболее поздние (последние по времени) актуальные записи регистра, сделанные до указанного момента времени включительно. Это самый распространенный срез, с помощью которого определяют текущую цену товара, действующий оклад сотрудника или курс валюты на дату документа.
  2. СрезПервых — получает наиболее ранние (первые по времени) записи регистра, сделанные начиная с указанного момента времени. Это позволяет узнать, например, первое будущее запланированное изменение цен, первую запись истории или факт первоначальной регистрации объекта после определенного числа.

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

Синтаксис и использование методов менеджера регистра

Платформа позволяет обращаться к срезам как через встроенный язык программирования (методы менеджера регистра сведений), так и через язык запросов. Разберем синтаксис встроенных методов.

Метод СрезПоследних имеет следующий формат:

РегистрСведенийМенеджер.<ИмяРегистра>.СрезПоследних(<КонецПериода>, <Отбор>)

Параметр КонецПериода определяет момент времени, заканчивая которым выбираются записи. Если дата не указана, выбирается самая последняя запись из имеющихся в базе. В параметре Отбор передается структура с конкретными значениями измерений. Метод возвращает объект ТаблицаЗначений.

Пример получения цен на текущий момент:


МаркетингЦен = РегистрыСведений.МаркетингЦен;
ТекущиеЦеныКонкурентов = МаркетингЦен.СрезПоследних(ТекущаяДата());

Метод СрезПервых имеет схожий синтаксис, но принимает параметр начала интервала:

РегистрСведенийМенеджер.<ИмяРегистра>.СрезПервых(<НачалоПериода>, <Отбор>)

Здесь НачалоПериода задает момент времени, начиная с которого будут искаться первые записи. Если параметр опущен, система найдет самые первые исторические записи регистра. Метод также возвращает объект ТаблицаЗначений.

Пример выборки цен, установленных начиная с сегодняшнего дня:


МаркетингЦен = РегистрыСведений.МаркетингЦен;
ОбновленныеСегодняЦены = МаркетингЦен.СрезПервых(ТекущаяДата());

Использование виртуальных таблиц в запросах и оптимизация производительности

В большинстве сценариев программисты 1С обращаются к виртуальным таблицам через язык запросов. Чтобы избежать критических проблем со скоростью выполнения запросов на больших базах, необходимо соблюдать строгие правила:

  1. Передавайте условия исключительно в параметры виртуальной таблицы, а не в секцию ГДЕ. Если наложить условие через ГДЕ, СУБД сначала рассчитает срез по всем миллионам строк регистра, сформирует неявную временную таблицу и только потом отфильтрует данные. Правильный вариант передачи отбора выглядит так:

ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних
  1. Параметры виртуальной таблицы не поддерживают связи с другими таблицами. В параметры СрезПоследних или СрезПервых нельзя передавать поля из других таблиц запроса через условия соединения. В них допустимы только константы, параметры запроса или простые логические выражения над полями самого регистра.
  2. Учитывайте индексацию измерений. Для периодического регистра платформа создает основной кластерный индекс: измерения (в порядке следования в конфигураторе) плюс период. Если в отбор передается только второе или третье измерение без первого, СУБД выполнит полное сканирование индекса. Чтобы ускорить выборку по независимому измерению, установите для него свойство Ведущее, что заставит платформу построить дополнительный индекс с включением периода.

Точность среза и объект «Граница»

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

Для управления включением граничного момента времени используем объект Граница:


ГраницаПериода = Новый Граница(ДокументСсылка.МоментВремени(), ВидГраницы.Исключая);
Запрос.УстановитьПараметр("Период", ГраницаПериода);

Если в регистре присутствуют две записи на абсолютно одинаковый момент времени, платформа разрешает коллизию следующим образом: для подчиненных регистратору регистров записи ранжируются по моменту времени документа-регистратора и номеру строки; для независимых регистров платформа в принципе запрещает создание дубликатов по одинаковому набору измерений и периоду.

Проблема среза на каждую дату в выборке

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

  1. Выгружаем пары «Объект — Дата документа» во временную таблицу.
  2. Соединяем реальную таблицу регистра с временной таблицей по условию Регистр.Период <= ВременнаяТаблица.Дата и с помощью группировки по объекту находим МАКСИМУМ(Регистр.Период).
  3. Повторно соединяем полученные максимальные даты с реальной таблицей регистра для извлечения ресурсов.

Таким образом, понимание принципов работы СрезПоследних и СрезПервых позволяет разработчику точно и оптимально выбирать данные на шкале времени, исключая ошибки и падение производительности информационной базы.

← На главную