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