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