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