При работе с непериодическими регистрами сведений в 1С:ЗУП часто возникает потребность получить только актуальное (последнее) состояние данных для каждого объекта, например, последнее подразделение или должность сотрудника. Поскольку такие регистры не имеют встроенного механизма СрезПоследних, нам необходимо реализовать эту логику с помощью языка запросов.
При решении данной задачи важно учитывать два критических нюанса:
Сотрудник часто приводит к получению некорректных данных, если у сотрудника имеется история записей.Сотрудник, поэтому ключ выборки должен быть точным, чтобы не терять записи.Рассмотрим вариант с использованием условия ГДЕ (Поле1, Поле2) В (ВЫБРАТЬ ...). Этот метод позволяет отобрать записи, где дата окончания является максимальной для конкретного сотрудника.
ВЫБРАТЬ
РегСотрудников.Сотрудник КАК Сотрудник,
РегСотрудников.Подразделение КАК Подразделение,
РегСотрудников.Окончание КАК Окончание
ИЗ
РегистрСведений.РегСотрудников КАК РегСотрудников
ГДЕ
(РегСотрудников.Сотрудник, РегСотрудников.Окончание) В
(ВЫБРАТЬ
РегСотрудников1.Сотрудник,
МАКСИМУМ(РегСотрудников1.Окончание)
ИЗ
РегистрСведений.РегСотрудников КАК РегСотрудников1
СГРУППИРОВАТЬ ПО
РегСотрудников1.Сотрудник)
Этот способ достаточно лаконичен, однако требует наличия индексов по полям Сотрудник и Окончание для высокой производительности на больших объемах данных.
Для сложных отчетов в 1С:ЗУП рекомендуется разбивать задачу на этапы с использованием временных таблиц. Это повышает читаемость кода и позволяет платформе эффективнее оптимизировать запрос.
Разберем алгоритм по шагам:
вт_ИзРН. Здесь же мы можем нормализовать даты, если в регистре используются «пустые» даты для обозначения бесконечности.вт_МаксимальныеДаты, в которой сгруппируем данные по сотруднику и получим максимальное значение Окончание.
// Шаг 1: Помещаем данные
ВЫБРАТЬ
Данные.Сотрудник,
Данные.Окончание,
Данные.Подразделение
ПОМЕСТИТЬ вт_ИзРН
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК Данные;
// Шаг 2: Находим максимальные даты
ВЫБРАТЬ
вт_ИзРН.Сотрудник,
МАКСИМУМ(вт_ИзРН.Окончание) КАК Окончание
ПОМЕСТИТЬ вт_МаксимальныеДаты
ИЗ
вт_ИзРН КАК вт_ИзРН
СГРУППИРОВАТЬ ПО
вт_ИзРН.Сотрудник;
// Шаг 3: Соединяем для получения результата
ВЫБРАТЬ
вт_ИзРН.Сотрудник,
вт_ИзРН.Подразделение,
вт_ИзРН.Окончание
ИЗ
вт_ИзРН КАК вт_ИзРН
ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_МаксимальныеДаты КАК ВТМ
ПО вт_ИзРН.Сотрудник = ВТМ.Сотрудник
И вт_ИзРН.Окончание = ВТМ.Окончание
При работе с подобными задачами в ЗУП обращайте внимание на следующие моменты:
Сотрудник или ФизическоеЛицо. Работа по ФизическоеЛицо часто приводит к потере данных по внутренним совместителям.3999.12.31 как маркер «бессрочности», обязательно используйте конструкцию ВЫБОР КОГДА для приведения таких дат к единому виду перед сравнением.Использование временных таблиц является «золотым стандартом» при разработке в 1С. Этот подход не только защищает от появления дублей в результатах выборки, но и делает вашу систему устойчивой к изменениям структуры данных в будущем.