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