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