Как выбрать последнюю запись из непериодического регистра сведений в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет IT и автоматизация бизнеса
← На главную

При работе с непериодическими регистрами сведений в 1С:ЗУП часто возникает потребность получить только актуальное (последнее) состояние данных для каждого объекта, например, последнее подразделение или должность сотрудника. Поскольку такие регистры не имеют встроенного механизма СрезПоследних, нам необходимо реализовать эту логику с помощью языка запросов.

Основные сложности задачи

При решении данной задачи важно учитывать два критических нюанса:

  1. Корреляция данных: Простая группировка по полю Сотрудник часто приводит к получению некорректных данных, если у сотрудника имеется история записей.
  2. Внутреннее совместительство: Один физический человек может занимать несколько позиций как разные Сотрудник, поэтому ключ выборки должен быть точным, чтобы не терять записи.

Решение 1: Использование коррелированного подзапроса

Рассмотрим вариант с использованием условия ГДЕ (Поле1, Поле2) В (ВЫБРАТЬ ...). Этот метод позволяет отобрать записи, где дата окончания является максимальной для конкретного сотрудника.


ВЫБРАТЬ
    РегСотрудников.Сотрудник КАК Сотрудник,
    РегСотрудников.Подразделение КАК Подразделение,
    РегСотрудников.Окончание КАК Окончание
ИЗ
    РегистрСведений.РегСотрудников КАК РегСотрудников
ГДЕ
    (РегСотрудников.Сотрудник, РегСотрудников.Окончание) В
        (ВЫБРАТЬ
            РегСотрудников1.Сотрудник,
            МАКСИМУМ(РегСотрудников1.Окончание)
        ИЗ
            РегистрСведений.РегСотрудников КАК РегСотрудников1
        СГРУППИРОВАТЬ ПО
            РегСотрудников1.Сотрудник)

Этот способ достаточно лаконичен, однако требует наличия индексов по полям Сотрудник и Окончание для высокой производительности на больших объемах данных.

Решение 2: Использование временных таблиц (Рекомендуемый подход)

Для сложных отчетов в 1С:ЗУП рекомендуется разбивать задачу на этапы с использованием временных таблиц. Это повышает читаемость кода и позволяет платформе эффективнее оптимизировать запрос.

Разберем алгоритм по шагам:

  1. Помещение данных во временную таблицу: Сначала выгрузим все нужные нам данные из регистра в таблицу вт_ИзРН. Здесь же мы можем нормализовать даты, если в регистре используются «пустые» даты для обозначения бесконечности.
  2. Вычисление максимума: Создадим вторую временную таблицу вт_МаксимальныеДаты, в которой сгруппируем данные по сотруднику и получим максимальное значение Окончание.
  3. Соединение: Соединим исходные данные с таблицей максимумов, чтобы отфильтровать только актуальные строки.

// Шаг 1: Помещаем данные
ВЫБРАТЬ
    Данные.Сотрудник,
    Данные.Окончание,
    Данные.Подразделение
ПОМЕСТИТЬ вт_ИзРН
ИЗ
    РегистрСведений.ДанныеДляПодбораСотрудников КАК Данные;

// Шаг 2: Находим максимальные даты
ВЫБРАТЬ
    вт_ИзРН.Сотрудник,
    МАКСИМУМ(вт_ИзРН.Окончание) КАК Окончание
ПОМЕСТИТЬ вт_МаксимальныеДаты
ИЗ
    вт_ИзРН КАК вт_ИзРН
СГРУППИРОВАТЬ ПО
    вт_ИзРН.Сотрудник;

// Шаг 3: Соединяем для получения результата
ВЫБРАТЬ
    вт_ИзРН.Сотрудник,
    вт_ИзРН.Подразделение,
    вт_ИзРН.Окончание
ИЗ
    вт_ИзРН КАК вт_ИзРН
ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_МаксимальныеДаты КАК ВТМ
    ПО вт_ИзРН.Сотрудник = ВТМ.Сотрудник
    И вт_ИзРН.Окончание = ВТМ.Окончание

Важные рекомендации

При работе с подобными задачами в ЗУП обращайте внимание на следующие моменты:

Использование временных таблиц является «золотым стандартом» при разработке в 1С. Этот подход не только защищает от появления дублей в результатах выборки, но и делает вашу систему устойчивой к изменениям структуры данных в будущем.

← На главную