При работе с периодическими регистрами сведений начинающие разработчики часто сталкиваются с ситуацией, когда виртуальная таблица СрезПоследних возвращает не одну «самую последнюю» запись, а целую группу строк. На первый взгляд это кажется ошибкой платформы, но на самом деле такое поведение обусловлено архитектурой системы 1С:Предприятие. В этой статье мы подробно разберем, как работает механизм среза, проанализируем типичные ошибки проектирования и выясним, как правильно составлять запросы для получения корректных данных.
Разберем фундаментальный принцип: виртуальная таблица СрезПоследних работает в разрезе всех уникальных комбинаций измерений. Это означает, что система ищет последнюю запись не вообще в регистре, а для каждого набора значений, входящих в измерения.
Рассмотрим ситуацию на примере. Если в вашем регистре три измерения — Сотрудник, Подразделение и РежимРаботы, то запрос к таблице СрезПоследних вернет одну строку для каждой уникальной комбинации этих трех полей. Если у сотрудника Иванова за его историю работы менялись подразделения или режимы, и эти поля являются измерениями, система обязана вернуть актуальную запись для каждого сочетания. Если вы ожидаете только одну строку по сотруднику, но получаете две — значит, значения в других измерениях различаются.
Проанализируем структуру регистра, которая чаще всего приводит к проблеме. Часто разработчики ошибочно включают в состав измерений поля, которые должны быть ресурсами или реквизитами.
Измерения — это набор полей, определяющих уникальность записи. В одну и ту же секунду (период) не может существовать двух записей с одинаковым набором измерений.
Ресурсы — это целевые данные, которые мы хотим получить (например, оклад, состояние, цена).
Реквизиты — вспомогательная информация о записи.
Если вы поместили поле Дата (созданное вручную) или поле Режим в измерения, система воспринимает их как часть уникального ключа. Рассмотрим пример: у нас есть сотрудник и измерение Режим (значения "Р" и "О"). Если в регистре есть запись для режима "Р" от 01.01.2023 и запись для режима "О" от 02.01.2023, то СрезПоследних вернет обе записи, так как для каждого уникального режима это будет «последняя» запись. Чтобы этого избежать, поле Режим должно быть ресурсом.
Выясним причину еще одной распространенной проблемы — низкой производительности и некорректной логики при использовании условия ГДЕ. Проанализируем разницу в подходах написания запроса.
Когда мы накладываем отбор в секции ГДЕ, система сначала строит срез последних по всем записям регистра, а уже потом фильтрует результат. Если записей миллионы, запрос будет крайне медленным. Правильный способ — передача условий в параметры виртуальной таблицы.
Посмотрим на пример правильного построения запроса:
ВЫБРАТЬ
РегистрСведенийСрезПоследних.Сотрудник,
РегистрСведенийСрезПоследних.Оклад,
РегистрСведенийСрезПоследних.Режим
ИЗ
РегистрСведений.СтавкиСотрудников.СрезПоследних(&Период, Сотрудник = &НужныйСотрудник) КАК РегистрСведенийСрезПоследних
В данном случае система сначала ограничит выборку конкретным сотрудником и только среди его записей найдет последнюю. Это работает быстро и исключает «шум» от других данных.
Рассмотрим технический нюанс, связанный со свойством измерения Основной отбор. В системе 1С это свойство влияет на индексацию данных. Если флаг установлен, по этому измерению создается индекс, который позволяет виртуальной таблице мгновенно находить нужные срезы. Хотя отсутствие этой галки не всегда напрямую приводит к дублированию строк в простых запросах, в сложных соединениях или при использовании вложенных запросов отсутствие индекса может сбивать оптимизатор запросов СУБД, что приводит к непредсказуемым результатам или пустым значениям.
Иногда две записи попадают в срез, потому что они были записаны в одну и ту же секунду. Для периодического регистра сведений крайне важно понимать разницу между Дата, МоментВремени и Граница.
НомерЗаписи), чтобы определить, какая из них последняя.Если вы обнаружили, что СрезПоследних выдает лишние строки, выполните следующие действия:
ДатаСоздания, Режим, ВидСобытия, которые являются лишь характеристиками, перенесите их в Ресурсы.СрезПоследних(Период, Условие), а не болтаются в ГДЕ.Дата в периодическом регистре. Для этого существует системное поле Период. Дополнительное измерение с типом Дата сделает каждую запись уникальной, и срез последних перестанет работать, превратившись в обычную выборку всех записей.Соблюдение этих правил обеспечит не только корректность получаемых данных, но и высокую скорость работы вашей конфигурации, особенно при росте объема накопленной информации в регистре.