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