Как программно получить количество работающих сотрудников в ЗУП 3.1 на определенную дату?

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

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

Способ 1. Запрос к интервальному регистру сведений

Начиная с версии 3.0, в ЗУП была внедрена концепция интервальных регистров. Основным источником данных здесь выступает регистр КадроваяИсторияСотрудниковИнтервальный. Рассмотрим подробнее, почему это удобнее, чем работа со срезом последних.

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


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

Запрос.УстановитьПараметр("ДатаСреза", НужнаяДата);
Запрос.УстановитьПараметр("Организация", СсылкаНаОрганизацию);
Результат = Запрос.Выполнить();

Важные моменты при работе с этим регистром:

  1. Исключение увольнений: Запись об увольнении в интервальном регистре также имеет свой период (часто до 31.12.3999). Если не добавить условие ВидСобытия <> Увольнение, в результат попадут сотрудники, которые уже не числятся в штате.
  2. Активность записей: Всегда проверяйте поле Активность. При перепроведении документов или исправлении кадровых цепочек система может помечать старые интервалы как неактивные.
  3. Границы периода: Логика МЕЖДУ корректно отрабатывает границы дат, что позволяет точно определить состояние сотрудника на любую секунду выбранного дня.

Способ 2. Использование функции КадровыйУчет.СотрудникиОрганизации

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

Эта функция учитывает множество внутренних проверок, включая права доступа (если установлен флаг ТолькоРазрешенные). Посмотрим на пример кода, который возвращает список сотрудников на дату:


// Подготавливаем параметры получения данных
ПараметрыЗапроса = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛиц();
ПараметрыЗапроса.НачалоПериода = НачалоДня(ВыбДата);
ПараметрыЗапроса.ОкончаниеПериода = КонецДня(ВыбДата);
ПараметрыЗапроса.Организация = СсылкаНаОрганизацию;

// Вызываем программный интерфейс
ТаблицаСотрудников = КадровыйУчет.СотрудникиОрганизации(Истина, ПараметрыЗапроса);

// Получаем количество
Количество = ТаблицаСотрудников.Количество();

Разберем параметры подробнее. Если нам нужно получить данные именно на один момент времени, мы устанавливаем НачалоПериода и ОкончаниеПериода равными этой дате. Функция вернет таблицу значений, где каждая строка — это уникальная связка "Сотрудник — Физическое лицо — Организация".

Способ 3. Оптимизированное получение через Временные Таблицы

Если вам необходимо получить количество сотрудников внутри собственного сложного запроса, наиболее эффективным методом будет использование программного формирования временной таблицы (ВТ). Рассмотрим этот алгоритм по шагам:

  1. Создаем менеджер временных таблиц (МВТ).
  2. Используем метод КадровыйУчет.СоздатьВТКадровыеДанныеСотрудников.
  3. Выполняем итоговый расчет из подготовленной таблицы.

Проанализируем пример реализации:


МВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МВТ;

// Формируем структуру полей, которые нам нужны (например, только ссылка на сотрудника)
КадровыеДанные = "Сотрудник, ФизическоеЛицо";

// Вызываем метод создания ВТ на дату
КадровыйУчет.СоздатьВТКадровыеДанныеСотрудников(МВТ, Истина, НужнаяДата, КадровыеДанные);

// Теперь мы можем обратиться к таблице ВТКадровыеДанныеСотрудников
Запрос.Текст = "ВЫБРАТЬ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Сотрудник) ИЗ ВТКадровыеДанныеСотрудников";
Количество = Запрос.Выполнить().Выгрузить()[0][0];

Этот способ является самым быстрым с точки зрения производительности системы, так как 1С оптимизирует запросы к базе данных, используя уже готовые механизмы срезов кадровой истории.

Важные нюансы: Сотрудники против Физических лиц

При подсчете количества важно понимать методологическую разницу между справочниками Сотрудники и ФизическиеЛица. Выясним, как это влияет на результат:

Внутреннее совместительство: Если один и тот же человек работает в организации на основной ставке и по внутреннему совместительству, в справочнике Сотрудники будет две разные записи. При использовании COUNT(Сотрудник) вы получите результат "2" (количество ставок). Если же ваша задача — посчитать "головы" (физических лиц), необходимо использовать COUNT(DISTINCT ФизическоеЛицо).

Работающие по договорам ГПХ: По умолчанию стандартные кадровые функции могут не включать договорников. Если в вашей задаче под "работающими" понимаются и те, кто работает по договорам гражданско-правового характера, вам потребуется дополнительно анализировать регистр ДанныеДоговоровСотрудников или расширять параметры запроса в модуле КадровыйУчет.

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

Таким образом, выбор метода зависит от контекста задачи. Для простых обработок подойдет СотрудникиОрганизации, для сложных отчетов — формирование временных таблиц, а для специфических выборок — прямой запрос к интервальному регистру с учетом вида кадрового события.

← На главную