Как в ЗУП 2.5 получить запросом последнее кадровое событие (прием или перемещение) перед увольнением?

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

В процессе сопровождения конфигурации 1С:Зарплата и Управление Персоналом 2.5 (на базе обычных форм) часто возникает задача корректного получения кадровой истории сотрудников. Особенно актуально это стало с введением отчетности СЗВ-ТД (ныне подразделы формы ЕФС-1). Типичный сценарий: для сотрудника, который увольняется, необходимо найти последнее легитимное кадровое событие — либо Прием на работу, либо последнее по дате Кадровое перемещение, игнорируя саму запись об увольнении.

В этой статье мы подробно проанализируем, как реализовать подобную выборку средствами языка запросов 1С, рассмотрим несколько подходов — от использования вложенных запросов до оптимизированной работы с виртуальными таблицами среза последних.

Анализ структуры данных

Основным источником кадровой информации в ЗУП 2.5 является периодический регистр сведений РаботникиОрганизаций. Его измерениями являются Сотрудник и Организация, а одним из ключевых ресурсов — ПричинаИзмененияСостояния. Это перечисление, которое может принимать значения: ПриемНаРаботу, Перемещение, Увольнение и другие.

Сложность задачи заключается в приоритетности: если у сотрудника было несколько перемещений после приема, нам нужно только последнее. Если перемещений не было — берем данные приема.

Вариант 1. Использование вложенных запросов и объединения

Рассмотрим первый способ решения, который базируется на логическом разделении событий приема и перемещения в разные временные таблицы или вложенные запросы с последующим их соединением. Проанализируем алгоритм:

  1. Создаем первый вложенный запрос для получения всех документов приема на работу.
  2. Создаем второй вложенный запрос для поиска последнего (максимального по дате) перемещения для каждого сотрудника.
  3. Соединяем эти данные с основной таблицей (например, с табличной частью документа увольнения), используя функцию ЕСТЬNULL для выбора приоритетной записи.

Посмотрим на пример реализации такого запроса:


ВЫБРАТЬ
    СЗВ_ТД_Мероприятия.Сотрудник КАК Сотрудник,
    ЕСТЬNULL(ВложенныйЗапросПеремещения.ПервичныйДокумент, ВложенныйЗапросПриемы.ПервичныйДокумент) КАК ИтоговыйДокумент,
    ЕСТЬNULL(ВложенныйЗапросПеремещения.Период, ВложенныйЗапросПриемы.Период) КАК ДатаСобытия
ИЗ
    Документ.СведенияОТрудовойДеятельностиРаботниковСЗВ_ТД.Мероприятия КАК СЗВ_ТД_Мероприятия
    
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Работники.Сотрудник КАК Сотрудник,
            Работники.ПервичныйДокумент КАК ПервичныйДокумент,
            Работники.Период КАК Период
        ИЗ
            РегистрСведений.РаботникиОрганизаций КАК Работники
        ГДЕ
            Работники.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.ПриемНаРаботу)
    ) КАК ВложенныйЗапросПриемы
    ПО СЗВ_ТД_Мероприятия.Сотрудник = ВложенныйЗапросПриемы.Сотрудник

    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Работники.Сотрудник КАК Сотрудник,
            МАКСИМУМ(Работники.ПервичныйДокумент) КАК ПервичныйДокумент,
            МАКСИМУМ(Работники.Период) КАК Период
        ИЗ
            РегистрСведений.РаботникиОрганизаций КАК Работники
        ГДЕ
            Работники.ПричинаИзмененияСостояния = ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Перемещение)
        СГРУППИРОВАТЬ ПО
            Работники.Сотрудник
    ) КАК ВложенныйЗапросПеремещения
    ПО СЗВ_ТД_Мероприятия.Сотрудник = ВложенныйЗапросПеремещения.Сотрудник
ГДЕ
    СЗВ_ТД_Мероприятия.Ссылка = &Ссылка

В данном примере мы используем конструкцию ЕСТЬNULL(ВложенныйЗапросПеремещения.ПервичныйДокумент, ВложенныйЗапросПриемы.ПервичныйДокумент). Она работает следующим образом: если для сотрудника найдено перемещение, будет выбрано оно. Если перемещений не найдено (результат соединения NULL), система возьмет документ из таблицы приемов.

Вариант 2. Оптимизированный запрос через СрезПоследних

Хотя первый вариант логически понятен, он может быть избыточным. Поскольку регистр РаботникиОрганизаций является периодическим, мы можем воспользоваться мощным механизмом виртуальных таблиц. Однако стандартный СрезПоследних без параметров вернет нам текущее состояние сотрудника (например, Увольнение), что нам не подходит.

Выясним, как правильно наложить фильтр. Мы можем передать условие непосредственно в параметры виртуальной таблицы. Проанализируем следующий пример:


ВЫБРАТЬ
    СЗВ_ТД_Мероприятия.Сотрудник КАК Сотрудник,
    РаботникиСрезПоследних.ПервичныйДокумент КАК ДокументОснование,
    РаботникиСрезПоследних.Период КАК ДатаМероприятия
ИЗ
    Документ.СведенияОТрудовойДеятельностиРаботниковСЗВ_ТД.Мероприятия КАК СЗВ_ТД_Мероприятия
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(
        &ПериодОтчета,
        ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
    ) КАК РаботникиСрезПоследних
    ПО СЗВ_ТД_Мероприятия.Сотрудник = РаботникиСрезПоследних.Сотрудник
ГДЕ
    СЗВ_ТД_Мероприятия.Ссылка = &Ссылка

Почему это работает лучше? Виртуальная таблица сначала отсекает все записи с причиной Увольнение, а уже среди оставшихся записей (приемы и перемещения) находит самую позднюю для каждого сотрудника. Это избавляет нас от необходимости делать несколько вложенных запросов и вручную определять приоритеты через ЕСТЬNULL.

Специфика отчетности СЗВ-ТД (ЕФС-1)

Если ваша цель — подготовка данных для трудовых книжек, необходимо учитывать несколько критических нюансов, характерных для ЗУП 2.5:

Подводим итоги

Мы рассмотрели два способа получения кадровой истории. Для простых отчетов и проверки данных идеально подходит вариант со СрезПоследних и фильтрацией внутри параметров виртуальной таблицы. Для сложных алгоритмов, где нужно четко разделять типы документов или обрабатывать специфические исключения, лучше использовать соединение вложенных запросов.

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

← На главную