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