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