Периодичность и срез последних
Вопрос про время в учёте: как из истории значений достать актуальное на нужную дату — и не перебирать записи руками.
Периодический регистр сведений хранит историю значений во времени, а срез последних (
СрезПоследних) возвращает по одной, самой свежей записи на заданную дату для каждой комбинации измерений.
Типичная формулировка: «Есть регистр сведений с ценами, которые меняются во времени. Как получить цену номенклатуры на конкретную дату?» Правильный ответ — виртуальная таблица СрезПоследних, а не выборка с сортировкой и ручным выбором первой строки. Этот вопрос отделяет тех, кто понимает периодичность, от тех, кто пишет запросы «в лоб».
Что такое периодичность
У регистра сведений есть свойство Периодичность: Непериодический, В пределах секунды, дня, месяца, квартала, года. Как только регистр становится периодическим, у него появляется стандартное поле Период, и по одной комбинации измерений может храниться несколько записей — по одной на каждый момент времени. Так регистр превращается в историю: цена была 1000 с января, стала 1200 с марта, 1500 с июня.
// История цен в периодическом регистре сведений "Цены"
// Период | Номенклатура | Цена
// 01.01.2026 | Кофе | 1000
// 01.03.2026 | Кофе | 1200
// 01.06.2026 | Кофе | 1500
СрезПоследних и СрезПервых
Чтобы получить актуальное значение, у периодического регистра есть две виртуальные таблицы. СрезПоследних(Дата, Отбор) — берёт последнюю запись на указанную дату (то есть с максимальным периодом, не превышающим дату). СрезПервых(Дата, Отбор) — наоборот, первую запись начиная с указанной даты. На практике в 90% случаев нужен именно СрезПоследних.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Цены.Номенклатура,
| Цены.Цена
|ИЗ
| РегистрСведений.Цены.СрезПоследних(&Дата, Номенклатура = &Номенклатура) КАК Цены";
Запрос.УстановитьПараметр("Дата", Дата('20260401000000'));
Запрос.УстановитьПараметр("Номенклатура", ВыбраннаяНоменклатура);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Сообщить("Цена на дату: " + Выборка.Цена); // вернёт 1200
КонецЕсли;
Результат:
Цена на дату: 1200
Обратите внимание: на 01.04.2026 срез вернул 1200 (запись от 01.03), а не 1500 — потому что июньская запись позже запрошенной даты. Это и есть смысл «среза последних на дату».
Быстрый способ без запроса
Если нужно одно значение, необязательно писать запрос — у менеджера регистра есть метод ПолучитьПоследнее:
Отбор = Новый Структура("Номенклатура", ВыбраннаяНоменклатура);
Значения = РегистрыСведений.Цены.ПолучитьПоследнее(Дата('20260401000000'), Отбор);
Цена = Значения.Цена; // 1200
Гранулярность периода — тонкий момент
Периодичность задаёт не только наличие поля Период, но и его «шаг». Если регистр периодичен «в пределах дня», то на одну комбинацию измерений в сутках может быть только одна запись — вторая запись за тот же день заместит первую. Это удобно для курсов валют (один курс на день), но станет ловушкой, если цена реально может меняться дважды в день: часть истории потеряется. Поэтому периодичность выбирают под характер данных, а «в пределах секунды» берут, когда важна точная хронология внутри дня. На собеседовании вопрос звучит как «почему у вас пропадают записи регистра» — и правильный ответ упирается именно в выбранную периодичность.
Ведущее измерение
Ещё один пункт, который любят спросить. У измерения регистра сведений есть флаг Ведущее. Он означает, что записи регистра логически подчинены значению этого измерения: если объект-измерение (например, конкретная Номенклатура) удаляется, вместе с ним автоматически удаляются и все связанные записи регистра. Кроме того, ведущее измерение влияет на отображение истории в форме объекта. Простыми словами: ведущее измерение = хозяин записей. Для регистра цен ведущим логично сделать Номенклатуру — цены без товара не нужны.
Как отвечать
Скажите так: «Чтобы значение менялось во времени, регистр сведений делаю периодическим — тогда по одной комбинации измерений хранится история с полем Период. Актуальное значение на дату получаю виртуальной таблицей СрезПоследних(&Дата, Отбор) — она возвращает по одной последней записи на дату для каждого набора измерений. Для единичного значения удобен метод ПолучитьПоследнее». Про ведущее измерение добавьте: «Это измерение-владелец: при удалении его значения связанные записи регистра удаляются автоматически». Такой ответ закрывает вопрос целиком.
Частые ошибки на собеседовании
- Выбирать историю и сортировать вручную. Запрос
УПОРЯДОЧИТЬ ПО Период УБЫВс выбором первой строки работает, но это переизобретениеСрезПоследних— медленнее и многословнее. - Забыть параметр даты в срезе.
СрезПоследних()без даты вернёт последние записи вообще, а не на нужный момент. Почти всегда дату нужно указывать. - Путать СрезПоследних и СрезПервых. «Последних» — последняя запись до/на дату (актуальное значение); «Первых» — первая начиная с даты.
- Думать, что периодический регистр хранит одно значение. Он хранит историю; одно значение — это уже результат среза.
- Не знать про ведущее измерение. Вопрос «что будет с записями регистра при удалении номенклатуры» ставит в тупик тех, кто пропустил этот флаг.
Итоги-шпаргалка
- Периодичность даёт регистру сведений поле
Периоди историю значений во времени. СрезПоследних(&Дата, Отбор)— последняя запись на дату;СрезПервых— первая начиная с даты.- Для одного значения удобен метод
ПолучитьПоследнее(Дата, Отбор). - Ведущее измерение — «владелец» записей: удаляется значение — удаляются связанные записи регистра.
- Не сортируйте историю вручную — для этого и есть виртуальные таблицы срезов.