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