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

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

В кадровом учете на платформе 1С:Предприятие 8, особенно в конфигурации «Зарплата и Управление Персоналом 2.5», одной из самых частых задач является получение списка сотрудников, которые числятся в штате на определенную дату. На первый взгляд задача кажется простой, но она таит в себе несколько подводных камней, связанных с работой виртуальных таблиц и логикой пакетных запросов. Рассмотрим подробно, как правильно составить запрос, чтобы исключить уволенных и получить данные об их приеме на работу.

Разберем логику работы виртуальной таблицы СрезПоследних

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

Если мы поместим условие ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение) в параметры виртуальной таблицы (внутрь скобок), система отработает следующим образом: она сначала отфильтрует все записи с причиной «Увольнение», а затем для каждого сотрудника найдет последнюю оставшуюся запись. Это означает, что если сотрудник был уволен, запрос вернет его предыдущее состояние (например, «Перемещение»), и программа посчитает его работающим. Это в корне неверно.

Для правильного отбора необходимо:

  1. Получить срез последних записей по всем сотрудникам без предварительной фильтрации по состоянию.
  2. Применить фильтр ГДЕ уже к результату этой виртуальной таблицы.

Проанализируем пример правильного отбора работающих сотрудников:


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

В этом случае сначала определяется актуальное состояние сотрудника на дату, а затем из этого списка исключаются те, у кого это состояние — увольнение.

Выясним причину проблем с пакетными запросами

Часто при работе с МенеджеромВременныхТаблиц программисты сталкиваются с тем, что метод Запрос.ВыполнитьПакет() возвращает не ожидаемую таблицу значений, а число. Посмотрим на ситуацию глубже: в языке запросов 1С операция ПОМЕСТИТЬ возвращает количество строк, которые были записаны во временную таблицу. Если ваш пакетный запрос состоит только из блоков ПОМЕСТИТЬ, вы не получите данные в привычном виде через Результат[i].Выгрузить().

Чтобы получить данные из временной таблицы в коде, у нас есть два пути:

  1. Добавить в конец пакета финальный запрос ВЫБРАТЬ * ИЗ ИмяВременнойТаблицы.
  2. Использовать метод менеджера временных таблиц: Запрос.МенеджерВременныхТаблиц.Таблицы["ИмяТаблицы"].ПолучитьДанные().Выгрузить().

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

Теперь объединим все знания, чтобы решить комплексную задачу: найти всех работающих на дату сотрудников и для каждого из них вытянуть первичную информацию из записи о приеме на работу. Для этого нам понадобится соединить срез последних (текущий статус) с физической таблицей регистра (история изменений).

Разберем по шагам структуру эффективного запроса:


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

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

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

Дополнительные рекомендации

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

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

Таким образом, использование виртуальной таблицы СрезПоследних с последующей фильтрацией в секции ГДЕ и грамотное соединение с физическими таблицами в рамках пакетного запроса — это наиболее надежный и профессиональный метод получения кадровых данных в 1С.

← На главную