Разработка и Конфигурация · 11 мин
Срез последних по регистру сведений 1С: как это работает и как использовать
Что такое срез последних по регистру сведений в 1С, как работает виртуальная таблица СрезПоследних, примеры запросов, типичные ошибки и советы по производительности.
Регистр сведений в 1С хранит историю изменений: цены номенклатуры, курсы валют, кадровые данные сотрудников. Но в отчётах и проведении документов почти всегда нужна не вся история, а одно актуальное значение на конкретную дату. Для этого в платформе предусмотрен механизм среза последних — специальная виртуальная таблица, которая возвращает по каждому объекту самую позднюю запись на указанный момент времени.
Механизм доступен только для периодических регистров сведений, то есть регистров, у которых установлена периодичность (в пределах секунды, дня, месяца и т.д.) и включён режим периодичности. Если регистр непериодический, виртуальная таблица «СрезПоследних» для него просто не существует — получать «последнее значение» придётся вручную через максимум по какому-либо реквизиту, что само по себе является признаком ошибки проектирования.
Понимание того, как устроен срез последних, критично для производительности: неправильно построенный запрос к этой таблице — одна из самых частых причин медленных отчётов и долгого проведения документов. Ниже разобрано устройство механизма, синтаксис, примеры запросов и типичные ошибки.
Что такое срез последних и как он устроен
Периодический регистр сведений хранит записи вида «период — измерения — ресурсы». Например, регистр «ЦеныНоменклатуры» хранит записи: 01.01 — цена 100, 15.03 — цена 120, 20.06 — цена 115. Срез последних на дату 01.05 вернёт одну запись — цену 120, потому что это самая поздняя запись, не превосходящая указанную дату.
Важно понимать: срез последних — не физическая таблица в базе данных, а виртуальная. Платформа строит её динамически при выполнении запроса. Физически данные лежат в одной таблице регистра, а срез формируется выборкой максимальных периодов по каждой комбинации измерений с последующим соединением с основной таблицей для получения ресурсов и реквизитов.
Если регистр подчинён регистратору (режим «Подчинение регистратору»), то при равенстве периодов приоритет имеет запись с более поздним моментом времени документа-регистратора. Для независимых регистров при совпадении периода поведение определяется уникальностью записей — платформа не позволит создать две записи с одинаковым периодом и одинаковыми значениями измерений.
Синтаксис виртуальной таблицы СрезПоследних
В языке запросов виртуальная таблица вызывается так: РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Условие). Первый параметр — дата (или момент времени), на которую строится срез. Если параметр не указан, срез строится на максимально возможную дату, то есть фактически возвращаются самые последние записи в регистре.
Второй параметр — условие отбора в виде строки на языке выражений запросов, например "Номенклатура В (&СписокНоменклатуры)". Условие накладывается на измерения до построения среза, что принципиально важно для производительности: платформа выберет записи только по нужным объектам, а не построит срез по всей таблице.
Пример типового запроса:
ВЫБРАТЬ
Срез.Номенклатура,
Срез.Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
&ДатаДокумента,
Номенклатура В (&СписокНоменклатуры)
) КАК Срез
// Программное получение среза последних без запроса
Отбор = Новый Структура("Номенклатура", ТекНоменклатура);
Значения = РегистрыСведений.ЦеныНоменклатуры.ПолучитьПоследнее(ДатаДокумента, Отбор);
Цена = Значения.Цена;Как получить срез последних программно
Для точечного чтения одного значения удобнее метод менеджера регистра ПолучитьПоследнее(Период, Отбор). Он возвращает структуру со значениями ресурсов последней записи по заданному отбору. Метод подходит, когда нужна цена одной позиции или курс одной валюты — писать полноценный запрос ради одного значения избыточно.
Однако в цикле по строкам документа вызывать ПолучитьПоследнее для каждой строки — антипаттерн. Сотня строк даст сотню обращений к базе. Правильный подход: один запрос к виртуальной таблице с отбором по списку номенклатуры, результат выгружается в таблицу значений или соответствие, и дальше данные берутся из памяти.
Также существует метод СрезПоследних(Период, Отбор) менеджера регистра, возвращающий таблицу значений. Он удобен для небольших выборок, но не поддерживает произвольные соединения и группировки — для сложной логики всегда используйте запрос.
Срез последних в отчётах и СКД
В схеме компоновки данных срез последних используется так же — через виртуальную таблицу в запросе набора данных. Период среза обычно передаётся параметром, который связывается с пользовательской настройкой отчёта. Удобный приём: назначить параметру выражение &КонецПериода из стандартного периода отчёта через вкладку «Компоновка данных».
Частая задача — показать в отчёте историю изменений с пометкой актуальной записи. Здесь срез последних соединяется с полной таблицей регистра по измерениям и периоду: записи, вошедшие в срез, получают признак «Актуальная». Это позволяет одним отчётом показать и динамику, и текущее состояние.
Если отчёт строится на каждый день периода (например, «цены на каждую дату месяца»), один срез не поможет — потребуется либо соединение с таблицей дат и группировка с максимумом периода, либо последовательные срезы. Такие запросы тяжёлые, их стоит оптимизировать через временные таблицы.
В типовых конфигурациях актуальные значения часто дублируются в реквизитах справочников или отдельных непериодических регистрах. Если нужно только текущее значение без истории, проверьте наличие такого дубля — чтение из него заметно быстрее построения среза.
Производительность: как не уложить базу срезом
Главное правило: всегда передавайте в виртуальную таблицу параметр периода и максимально узкое условие отбора по измерениям. Срез без условий по регистру с миллионами записей заставит СУБД сгруппировать всю таблицу — на больших объёмах это секунды и десятки секунд на каждый запрос.
Второе правило: не помещайте срез последних в пакетный запрос с соединениями «на всякий случай», если данные среза нужны только при определённом условии. Каждое обращение к виртуальной таблице — это подзапрос с группировкой. Проверяйте план запроса: если видите сканирование всей таблицы регистра, значит, отбор не попал в параметры виртуальной таблицы.
Третий аспект — индексы. Платформа автоматически строит индекс по измерениям и периоду, поэтому отбор по полному составу измерений работает быстро. Отбор по части измерений или по реквизитам (не измерениям) в параметрах виртуальной таблицы невозможен — реквизиты можно фильтровать только в секции ГДЕ основного запроса, после построения среза.
Срез последних и срез первых: в чём разница
У периодического регистра есть и вторая виртуальная таблица — СрезПервых. Она возвращает самую раннюю запись на дату или после неё: по каждому сочетанию измерений выбирается запись с минимальным периодом, большим или равным указанному. Типовой сценарий — узнать, когда цена изменится в следующий раз, или найти первое назначение сотрудника после даты приёма.
Синтаксис идентичен: РегистрСведений.Имя.СрезПервых(&Период, Условие). Ограничения те же: таблица доступна только для периодических регистров, отбор работает по измерениям, а производительность зависит от узости условия.
Сравнение вариантов
Актуальное значение на дату: цены, курсы, ставки, ФИО. Самый частый сценарий в документах и отчётах.
Ближайшее будущее или первое значение после даты: дата следующего изменения цены, первое кадровое назначение.
История изменений, аналитика динамики. Тяжелее среза, но даёт все записи за период.
Как проверить правильность полученного среза
Самый надёжный способ проверки — сравнить результат запроса с данными формы списка регистра. Откройте регистр в режиме предприятия, установите отбор по конкретному измерению (например, одной номенклатуре), отсортируйте по периоду по убыванию и найдите первую запись, не превышающую дату среза. Её значения должны совпасть с результатом запроса.
Второй признак корректности — количество строк. Срез последних не может вернуть больше строк, чем существует уникальных комбинаций измерений в отобранном диапазоне. Если вы запросили срез по ста позициям номенклатуры, а получили сто пятьдесят строк, значит, в запросе лишнее соединение или дубли в исходной таблице отбора.
Отдельно проверяйте граничные случаи: позиции, по которым в регистре нет ни одной записи до даты среза, в результат просто не попадут. Если бизнес-логика требует строку с пустым значением, используйте левое соединение от списка номенклатуры к срезу, а не наоборот.
Как проверить результат
Последняя запись до даты среза совпадает с результатом запроса
Запрос вернул более позднюю запись — вероятно, не передан параметр периода
Не больше числа уникальных комбинаций измерений
Строк больше — дубли из-за соединения или повторов в таблице отбора
Отсутствуют в результате или имеют NULL при левом соединении
Позиция потерялась там, где должна быть строка с пустым значением
Доли секунды при отборе по измерениям
Секунды на небольшом отборе — условие не передано в параметры виртуальной таблицы
FAQ
Можно ли получить срез последних для непериодического регистра сведений?
Нет, виртуальные таблицы СрезПоследних и СрезПервых существуют только у периодических регистров. Для непериодического регистра понятие «последний» не определено — записи не имеют периода. Если актуальность по дате нужна, регистр следует сделать периодическим на этапе проектирования.
Что вернёт срез последних, если не указать дату?
Срез будет построен на максимальную дату, то есть вернутся самые последние записи регистра по каждому сочетанию измерений. Это удобно для получения текущих значений, но опасно в проведении документов задним числом — значение окажется «из будущего» относительно даты документа.
Почему запрос со срезом последних работает медленно?
Наиболее вероятная причина — отсутствие условия в параметрах виртуальной таблицы: платформа строит срез по всем записям регистра. Перенесите отбор по измерениям из секции ГДЕ во второй параметр виртуальной таблицы и убедитесь, что в отбор попадают только нужные объекты, например через временную таблицу со списком номенклатуры.
Можно ли в условии виртуальной таблицы отфильтровать по ресурсу или реквизиту?
Нет, в параметрах виртуальной таблицы допустимы отборы только по измерениям (и периоду). Фильтрацию по ресурсам и реквизитам выполняйте в секции ГДЕ основного запроса — она применится к уже построенному срезу.
Что делать, если на одну дату в регистре несколько записей по одному объекту?
Для независимого регистра платформа не допускает двух записей с одинаковым периодом и измерениями. Для регистра, подчинённого регистратору, такие записи возможны, и срез выберет запись с более поздним моментом времени регистратора. Если логика требует иного, приоритет нужно задавать явно через упорядочивание в собственном запросе вместо виртуальной таблицы.
Чем срез последних отличается от соединения с максимумом периода вручную?
По сути виртуальная таблица делает то же самое: группировку по измерениям с максимумом периода и соединение с основной таблицей. Ручной запрос оправдан, когда нужна нестандартная логика — например, срез на несколько дат одновременно или особый приоритет при равных периодах. В остальных случаях штатная виртуальная таблица проще и читаемее.
Что важно запомнить
Срез последних — виртуальная таблица периодического регистра сведений, возвращающая актуальную запись по каждому объекту на заданную дату. Всегда передавайте период и отбор по измерениям в параметры виртуальной таблицы, не вызывайте ПолучитьПоследнее в цикле и проверяйте результат по форме списка регистра. Для непериодических регистров срез недоступен.