Как в отчете СКД ЗУП 3.0 вывести колонку «Уволен из числа принятых» за период?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

Приветствуем вас! При создании кадровой отчетности в программе «1С:Зарплата и управление персоналом 3» (ЗУП 3.0 / 3.1) перед аналитиками и разработчиками часто возникает задача детального анализа текучести кадров. Типичный пример — определить сотрудников, которые не просто уволились в течение определенного периода, а были приняты на работу и уволены в рамках этого же временного интервала. Такой показатель в кадровом учете часто называют «уволен из числа принятых».

В этой статье мы подробно рассмотрим, как решить данную задачу в системе компоновки данных (СКД). Мы проанализируем архитектурные особенности ЗУП 3, разберем, почему стандартные подходы со срезами последних здесь не работают, и предложим несколько вариантов реализации — от простого запроса к физическим таблицам до профессионального использования встроенных механизмов представлений и настройки отчета вообще без программирования.

Архитектурное отличие ЗУП 3 от старых версий (Сотрудник vs Физическое лицо)

Прежде чем приступать к написанию запроса, нам необходимо учесть одну важную архитектурную деталь ЗУП 3, которая отличает её от ЗУП 2.5 или УПП 1.3. В старых конфигурациях один и тот же элемент справочника СотрудникиОрганизаций мог многократно увольняться и приниматься заново. Это усложняло запросы, вынуждая разработчиков писать сложные конструкции с поиском максимальных дат.

В ЗУП 3 логика учета изменилась:

  1. Один трудовой договор равен одному элементу справочника Сотрудники.
  2. Если сотрудник увольняется, а затем через какое-то время снова принимается в ту же компанию, для него создается новый элемент в справочнике Сотрудники. При этом карточка в справочнике Физические лица остается единой.

Эта особенность существенно упрощает нашу задачу. Для конкретного элемента справочника Сотрудники в системе может существовать не более одного приема и не более одного увольнения. Проводя левое соединение по полю Сотрудник, мы гарантированно остаемся в рамках одного трудового договора и исключаем наложение истории предыдущих периодов работы этого человека.

Почему нельзя использовать СрезПоследних

Частой ошибкой начинающих разработчиков является попытка получить кадровые данные через виртуальную таблицу СрезПоследних регистра сведений КадроваяИсторияСотрудников. Выясним причину, почему в данном случае это приведет к некорректным результатам.

Виртуальная таблица СрезПоследних возвращает наиболее актуальную запись на определенный момент времени. Если сотрудник был принят и уволен внутри выбранного периода, то на конечную дату периода срез вернет событие «Увольнение». Информация о том, что ранее в этом же периоде было событие «Прием», просто сотрется из результатов среза. Нам же необходимо анализировать всю историю изменений за период, поэтому мы должны работать непосредственно с таблицей физического регистра кадровой истории или использовать специализированные интервальные механизмы.

Способ 1. Реализация через запрос СКД (Левое соединение событий регистра)

Рассмотрим первый, наиболее очевидный способ решения задачи с помощью написания запроса в СКД. Нам потребуется выбрать всех сотрудников, уволенных за период, а затем соединить их с записями о приемах за этот же период.

Разберем логику построения запроса по шагам:

  1. Создаем временную таблицу УволенныеЗаПериод, в которую выбираем всех сотрудников с событием «Увольнение» за указанный пользователем период.
  2. Делаем выборку из этой временной таблицы и соединяем её левым соединением с физической таблицей кадровой истории, фильтруя записи по событию «Прием» и проверяя, чтобы дата приема также входила в наш интервал.
  3. Добавляем вычисляемое поле, которое вернет Истина, если дата приема найдена, и Ложь в противном случае.

Проанализируем пример текста такого запроса:


ВЫБРАТЬ
    КадроваяИстория.Сотрудник КАК Сотрудник,
    КадроваяИстория.Период КАК ДатаУвольнения
ПОМЕСТИТЬ УволенныеЗаПериод
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИстория
ГДЕ
    КадроваяИстория.Период МЕЖДУ &НачалоПериода И &КонецПериода
    И КадроваяИстория.ВидСобытия = ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Уволенные.Сотрудник КАК Сотрудник,
    Уволенные.ДатаУвольнения КАК ДатаУвольнения,
    ЕСТЬNULL(Приемы.Период, ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)) КАК ДатаПриемаВПериоде,
    ВЫБОР
        КОГДА Приемы.Период ЕСТЬ NULL
            ТОГДА ЛОЖЬ
        ИНАЧЕ ИСТИНА
    КОНЕЦ КАК УволенИзЧислаПринятых
ИЗ
    УволенныеЗаПериод КАК Уволенные
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников КАК Приемы
        ПО Уволенные.Сотрудник = Приемы.Сотрудник
        И Приемы.ВидСобытия = ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Прием)
        И Приемы.Период МЕЖДУ &НачалоПериода И &КонецПериода

В результате выполнения этого запроса мы получаем готовую выборку, в которой для каждого уволенного сотрудника будет выведена дата увольнения, дата приема (если она была в этом же периоде) и флаг УволенИзЧислаПринятых, который можно вывести в СКД в качестве отдельной колонки.

Способ 2. Использование механизма представлений ЗУП 3.0 (Профессиональный подход)

Прямой запрос к физическому регистру КадроваяИсторияСотрудников, рассмотренный выше, прост для понимания, однако в реальной базе ЗУП 3 он может выдавать ошибки. Например, при наличии исправлений документов «задним числом», временных кадровых переводов или увольнений в один день с приемом.

Для предотвращения подобных ошибок в ЗУП 3 разработан **механизм представлений кадровых данных** — виртуальный API для запросов. Чтобы применить его в СКД, выполним следующие действия:

  1. В схеме компоновки данных нашего отчета пишем запрос, формирующий временную таблицу сотрудников, по которым нужны данные (например, ВТСотрудники с полями Сотрудник и Период).
  2. Ниже в тексте запроса обращаемся к виртуальной таблице-шаблону Представления_КадровыеДанныеСотрудников, запрашивая готовые поля ДатаПриема и ДатаУвольнения.
  3. Чтобы этот шаблон преобразовался в реальный работающий запрос, в модуле объекта отчета в процедуре ПриКомпоновкеРезультата необходимо прописать вызов стандартного метода:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Автоматическое заполнение кадровых данных через механизм представлений ЗУП
    ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Этот метод автоматически сформирует сложный и оптимизированный SQL-запрос к интервальным регистрам системы, который вернет абсолютно точные кадровые даты без риска получить пустые значения или лишние строки.

Способ 3. Программное получение данных через общий модуль

Если данные необходимо получить программно (например, для передачи их в СКД через внешний набор данных), вместо написания запросов лучше использовать готовую функцию общего модуля ЗУП:


КадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(
    Истина, 
    СписокСотрудников, 
    "ДатаПриема, ДатаУвольнения", 
    КонецПериода
);

Функция самостоятельно обратится к нужным интервальным регистрам системы, применит все контроли прав доступа и вернет готовую таблицу значений с полями Сотрудник, ДатаПриема и ДатаУвольнения. Далее останется лишь наложить простое условие проверки периода в коде обхода таблицы:


Для Каждого СтрокаИзТаблицы Из КадровыеДанные Цикл
    Если СтрокаИзТаблицы.ДатаПриема >= НачалоПериода И СтрокаИзТаблицы.ДатаПриема <= КонецПериода Тогда
        // Сотрудник был и принят, и уволен за этот период
        СтрокаИзТаблицы.УволенИзЧислаПринятых = Истина;
    КонецЕсли;
КонецЦикла;

Способ 4. Настройка отчета в режиме пользователя (Без изменения кода)

Подобный отчет можно собрать в режиме «1С:Предприятие» силами пользователя, используя возможности СКД в стандартных кадровых отчетах. Разберем по шагам, как это сделать:

  1. Откроем типовой отчет «Уволенные сотрудники» (или «Кадровые изменения»).
  2. Перейдем в «Настройки», затем выберем вид настроек «Расширенный».
  3. На вкладке «Поля и сортировка» добавим стандартные поля: Работа.Дата приема и Работа.Дата увольнения.
  4. Нажмем кнопку «Добавить пользовательское поле» и выберем «Новое поле-выбор».
  5. Зададим имя для нового поля: Уволен из числа принятых.
  6. В окне настроек добавим условие:
    • Поле: Работа.Дата приема
    • Вид сравнения: Больше или равно
    • Значение: выберем параметр данных НачалоПериода
  7. В качестве выводимого значения при выполнении условия укажем Да (или Истина), в поле «Иначе» укажем Нет (или Ложь).
  8. Выведем это созданное пользовательское поле в список выбранных полей отчета и сформируем результат.

Этот способ позволяет решить задачу за несколько минут без изменения конфигурации и написания какого-либо программного кода, полностью используя встроенную в ЗУП 3 логику СКД.

Мы детально проанализировали четыре различных подхода к решению этой аналитической задачи. Выберите тот вариант, который лучше всего подходит для ваших текущих задач автоматизации кадрового учета!

← На главную