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