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