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

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

При разработке проверочных отчетов для кадрового учета и статистики в программе 1С:Зарплата и управление персоналом 3.1 часто возникает необходимость получить данные не просто на начало или конец месяца, а в разрезе каждого календарного дня. Это требуется для проверки среднесписочной численности (ССЧ), анализа занятости совместителей и контроля нахождения сотрудников в отпусках по уходу за ребенком ("декретницы").

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

Метод 1. Использование типового API модуля КадровыйУчет

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

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


// Формируем массив сотрудников (ссылки на справочник Сотрудники)
МассивСотрудников = Новый Массив;
// ... заполнение массива ...

// Вызываем функцию API для получения данных на дату окончания периода
СписокПолей = "Сотрудник,ДатаПриема,ДатаУвольнения,ВидЗанятости,ФизическоеЛицо";
ТЗКадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(Истина, МассивСотрудников, СписокПолей, КонецМесяца(ПериодОтчета));

Для Каждого СтрокаДанных Из ТЗКадровыеДанные Цикл
    // Здесь мы получаем периоды работы сотрудника
    НачалоРаботы = СтрокаДанных.ДатаПриема;
    КонецРаботы = ?(ЗначениеЗаполнено(СтрокаДанных.ДатаУвольнения), СтрокаДанных.ДатаУвольнения, Дата(3999, 12, 31));
    
    // Теперь мы можем перебрать все дни месяца и проверить, работал ли сотрудник
    ТекущийДень = НачалоМесяца(ПериодОтчета);
    Пока ТекущийДень <= КонецМесяца(ПериодОтчета) Цикл
        Если ТекущийДень >= НачалоРаботы И ТекущийДень <= КонецРаботы Тогда
            // Сотрудник числится в штате на эту дату
            // Выполняем инкремент счетчика или запись в таблицу результатов
        КонецЕсли;
        ТекущийДень = ТекущийДень + 86400; // Переход к следующему дню
    КонецЦикла;
КонецЦикла;

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

Метод 2. Использование интервальных регистров в запросе

Если нам нужна высокая скорость работы, особенно при больших объемах данных, следует обратиться к интервальным регистрам. В ЗУП 3.1 данные о кадровой истории, состояниях и видах занятости хранятся в специальных регистрах, где каждая запись — это не просто «срез на дату», а готовый интервал ДатаНачала и ДатаОкончания.

Проанализируем ключевые регистры для нашей задачи:

  1. ВидыЗанятостиСотрудниковИнтервальный — поможет отделить основных сотрудников от внешних совместителей.
  2. СостоянияСотрудниковИнтервальный — содержит информацию о нахождении в отпусках (включая декретные), командировках и т.д.
  3. КадроваяИсторияСотрудниковИнтервальный — основной источник данных о подразделениях, должностях и количестве занимаемых ставок.

Рассмотрим структуру запроса, который позволяет получить данные на каждый день. Основная идея заключается в создании виртуальной таблицы дат (календаря) и её соединении с интервальным регистром по условию вхождения даты в интервал.


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

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

Метод 3. Анализ механизмов отчета "Статистика персонала"

Если ваша задача — сделать проверочный отчет для статистики, стоит выяснить, как именно программа считает данные в типовых формах. В ЗУП 3.1 существует мощный внутренний механизм формирования временных таблиц для статистических отчетов.

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

Также обратите внимание на функцию УчетСреднесписочнойЧисленности.ПолучитьДанныеДляРасчетаСреднейЧисленности. Она возвращает таблицу со всеми необходимыми показателями:

Эта функция учитывает исключаемые периоды (например, прогулы или те же декретные отпуска), что крайне важно для корректности проверки.

Нюансы учета декретниц и совместителей

При построении алгоритма проверки важно учитывать следующие правила:

  1. Совместители: Внешние совместители не входят в среднесписочную численность, но учитываются в средней численности. Внутренние совместители учитываются как одна единица по основному месту работы.
  2. Декретницы: Сотрудницы в отпусках по беременности и родам и по уходу за ребенком исключаются из среднесписочной численности. Чтобы их найти, анализируем регистр СостоянияСотрудников. Нам нужны записи, где значение перечисления СостоянияСотрудника соответствует ОтпускПоБеременностиИРодам или ОтпускПоУходуЗаРебенком.
  3. Ставки: Для сотрудников с неполным рабочим днем статистика часто считается пропорционально отработанному времени или занимаемой ставке. Эти данные хранятся в КадроваяИсторияСотрудниковИнтервальный.КоличествоСтавок.

Итоговый алгоритм реализации

Выясним наиболее эффективную последовательность действий для разработки вашего отчета:

1. Подготовка календаря: Создаем временную таблицу, содержащую все даты выбранного периода (например, через запрос к производственному календарю или генерацию чисел).

2. Получение интервалов занятости: Делаем запрос к интервальным регистрам (Кадровая история, Виды занятости), ограничивая выборку нужной организацией.

3. Соединение: Соединяем календарь с интервалами. Это даст нам базу "Сотрудник + Дата".

4. Наложение состояний: Присоединяем данные из регистра состояний. Если на конкретную дату у сотрудника зафиксировано состояние "Отпуск по уходу...", ставим признак "Декретница".

5. Группировка и расчет: Сворачиваем таблицу по датам и категориям (штатные, совместители, декретницы), вычисляя количество записей для каждой категории.

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

← На главную