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