Интервальные регистры ЗУП 3.1 — это непериодические двойники кадровых и расчётных регистров сведений, где каждая запись хранит не дату изменения, а интервал действия значения: ДатаНачала и ДатаОкончания (у открытого интервала — 31.12.3999). Чтобы узнать подразделение или оклад сотрудника на дату, не нужен срез последних — достаточно условия «дата между началом и окончанием». Пишутся такие регистры автоматически при записи основного регистра, вручную их не трогают.
Ниже — зачем это сделано, как устроены интервалы, как писать запросы в доработках и что делать, если интервальные данные разошлись с основными.
Проблема срезов последних
В периодическом регистре сведений хранится момент изменения: «с 01.03 оклад 80 000». Чтобы узнать оклад на 15.04, платформа строит виртуальную таблицу СрезПоследних — ищет последнюю запись до этой даты. Для одного сотрудника на одну дату это дёшево.
В зарплатных задачах так не бывает. Расчёт и отчёты требуют состояния сотрудников на каждый день периода: табель, начисления пропорционально отработанному времени, кадровые отчёты за год. Срез последних на каждую дату для сотен и тысяч сотрудников превращается в тяжёлые запросы с соединениями по МАКСИМУМ(Период), и нагрузка на СУБД растёт кратно.
Интервальные регистры решают это ценой избыточности: те же данные хранятся второй раз, но в форме, удобной для чтения.
Как устроен интервальный регистр

| Периодический регистр | Интервальный регистр | |
|---|---|---|
| Периодичность | Периодический, есть поле Период | Непериодический |
| Как хранится состояние | Дата изменения и новое значение | Интервал ДатаНачала — ДатаОкончания и значение |
| Получение на дату | Виртуальная таблица СрезПоследних | Условие по интервалу |
| Кто пишет | Документы-регистраторы | Механизм БЗК при записи основного регистра |
| Пример | КадроваяИсторияСотрудников | КадроваяИсторияСотрудниковИнтервальный |
Пример. Сотрудник принят 01.02 с окладом 70 000, с 01.06 оклад повышен до 85 000.
В основном регистре две записи: «01.02 — 70 000» и «01.06 — 85 000». В интервальном тоже две, но иначе:
| ДатаНачала | ДатаОкончания | Значение |
|---|---|---|
| 01.02 00:00:00 | 31.05 23:59:59 | 70 000 |
| 01.06 00:00:00 | 31.12.3999 23:59:59 | 85 000 |
Интервалы идут встык, без пропусков и наложений, — это гарантирует механизм формирования.
Время в ДатаНачала
Тонкость, на которой спотыкаются при доработках. Если в одних сутках несколько изменений (приём и тут же перевод, исправление документа), механизм вытеснения упорядочивает их внутри дня и проставляет время, отличное от 00:00:00. Поэтому параметр даты в запросе приводите к концу дня:
Запрос.УстановитьПараметр("НаДату", КонецДня(ДатаОтчета));Иначе изменения, внесённые в этот день не в полночь, в выборку не попадут.
Запросы к интервальному регистру
Состояние на дату:
ВЫБРАТЬ
История.Сотрудник КАК Сотрудник,
История.Подразделение КАК Подразделение,
История.Должность КАК Должность
ИЗ
РегистрСведений.КадроваяИсторияСотрудниковИнтервальный КАК История
ГДЕ
История.Сотрудник В (&Сотрудники)
И &НаДату МЕЖДУ История.ДатаНачала И История.ДатаОкончанияВсе состояния, действовавшие в периоде, — условие пересечения интервалов:
ВЫБРАТЬ
История.Сотрудник КАК Сотрудник,
История.Подразделение КАК Подразделение,
История.Должность КАК Должность,
История.ДатаНачала КАК ДатаНачала,
История.ДатаОкончания КАК ДатаОкончания
ИЗ
РегистрСведений.КадроваяИсторияСотрудниковИнтервальный КАК История
ГДЕ
История.Сотрудник = &Сотрудник
И История.ДатаНачала <= &КонецПериода
И История.ДатаОкончания >= &НачалоПериода&КонецПериода — тоже конец дня. Такой запрос вернёт все кадровые изменения, затронувшие период, одним прямым чтением.
Главное преимущество проявляется в соединениях. Таблицу дней периода можно соединить с интервальным регистром по условию «день внутри интервала» и получить состояние сотрудника на каждый день — без подзапросов со срезами.
Прямые запросы или программный интерфейс БЗК
Запросы выше полезны, чтобы понять механизм, и для разовой диагностики. В доработках типовой ЗУП я стараюсь не обращаться к интервальным регистрам напрямую, а использовать программный интерфейс библиотеки БЗК. Например, кадровые данные на дату удобно получать через КадровыйУчет.КадровыеДанныеСотрудников:
// Получает подразделение и должность сотрудников на дату через программный интерфейс БЗК.
КадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(Истина, МассивСотрудников,
"Подразделение,Должность", ДатаОтчета);
Для Каждого Строка Из КадровыеДанные Цикл
// Строка.Сотрудник, Строка.Подразделение, Строка.Должность
КонецЦикла;Почему так лучше:
- внутренняя структура регистров меняется от релиза к релизу, а программный интерфейс сохраняется;
- интерфейс учитывает права доступа и особенности хранения, которые легко упустить в собственном запросе;
- после обновления конфигурации меньше шансов, что доработка сломается.
Точный состав параметров смотрите в описании функции в вашем релизе: в БЗК есть варианты, возвращающие таблицу значений, и варианты, создающие временную таблицу в менеджере временных таблиц для использования в своих запросах. Отчёты по кадровым данным я обычно делаю как отчёты на СКД поверх этих механизмов.
Если данные разъехались
Интервальный регистр — по сути кэш, а у любого кэша бывают расхождения с источником. Причины:
- доработка, которая пишет в основной регистр набором записей в обход документов и механизмов БЗК;
- прерванная загрузка или обмен данными;
- ручная правка регистров через обработки редактирования.
Симптомы: кадровый отчёт показывает старое подразделение, расчёт берёт прежний оклад, хотя документ проведён.
Порядок действий:
- Перепровести документы сотрудника. При записи регистратора интервалы по этому сотруднику пересчитываются.
- Перезаполнить интервальные регистры штатной командой администрирования конфигурации. Для больших баз это долгая операция: планируйте её на нерабочее время и делайте резервную копию.
- Программно: в БЗК есть процедуры обновления движений интервального регистра для отбора сотрудников. Имена и параметры отличаются в разных релизах, поэтому перед использованием найдите актуальную процедуру поиском по общим модулям.
Если расхождения возвращаются, ищите причину в доработках. В своих расширениях к ЗУП я не пишу в кадровые регистры напрямую — только через документы или программный интерфейс, тогда интервалы обновляются сами. Такой контроль — часть нормальной доработки 1С:ЗУП. Если кадровые отчёты всё равно формируются долго, причину ищут уже на уровне аудита производительности.
Интервальный регистр — это кэш для чтения. Пишите в источник, а кэш пусть обновляет механизм, который за него отвечает.
Типичные ошибки разработчика
- Параметр даты не приведён к концу дня — пропадают изменения последнего дня.
- Попытка записать интервальный регистр вручную из доработки.
- Запрос со срезом последних по основному регистру в цикле по дням, хотя есть интервальный двойник.
- Прямые запросы к интервальным регистрам в тиражируемом расширении, которые ломаются после обновления.
- Отсутствие пункта «перезаполнить интервальные регистры» в инструкции для поддержки: многие «странные» данные лечатся именно этим.
Итог
- Интервальные регистры ЗУП 3.1 хранят кадровую и расчётную историю в виде интервалов
ДатаНачала—ДатаОкончания. - Состояние на дату получается простым условием вместо среза последних, что сильно ускоряет отчёты и расчёт.
- Регистры ведомые: их формирует механизм БЗК при записи основных регистров, вручную в них не пишут.
- В запросах приводите даты к концу дня, а в доработках по возможности используйте программный интерфейс БЗК.
- При расхождениях — перепроведение документов и перезаполнение интервальных регистров, затем поиск доработки-виновника.




