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