Как получить количество работающих сотрудников и их ставки по подразделениям в 1С:ЗУП 3.1

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

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

Особенности кадрового учета в ЗУП 3.1: почему обычный срез последних может ошибаться

Прежде чем перейти к написанию запросов, проанализируем ситуацию с кадровой историей. Использование стандартной виртуальной таблицы СрезПоследних к регистру сведений КадроваяИсторияСотрудников — самый очевидный, но не всегда надежный путь. Основная проблема кроется во временных кадровых переводах. Если сотрудника временно перевели в другое подразделение, а срок перевода уже истек, в регистре истории кадровых событий не создается новая запись о "возврате" на прежнее место работы. В результате простой срез последних покажет устаревшую и некорректную информацию.

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

Решение 1. Быстрый запрос на текущую дату (регистр «Текущие кадровые данные»)

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

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


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

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

Решение 2. Запрос на произвольную дату через кадровые регистры

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

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


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

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

Решение 3. Использование официального API (Кадровый учет) — рекомендуемый метод

Чтобы ваш код не сломался после очередного обновления релиза ЗУП 3.1, фирма "1С" настоятельно рекомендует использовать готовые методы общего модуля КадровыйУчет. Этот программный интерфейс самостоятельно учитывает все нюансы временных переводов, рассчитывает интервалы и формирует правильные временные таблицы на лету.

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


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

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

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

// Формируем результирующий запрос по созданной виртуальной таблице
Запрос.Текст = 
"ВЫБРАТЬ
|   КадровыеДанные.Организация КАК Организация,
|   КадровыеДанные.Подразделение КАК Подразделение,
|   СУММА(КадровыеДанные.КоличествоСтавок) КАК ЗанятоСтавок,
|   КОЛИЧЕСТВО(РАЗЛИЧНЫЕ КадровыеДанные.Сотрудник) КАК КоличествоРаботающих,
|   СУММА(ВЫБОР 
|       КОГДА КадровыеДанные.КоличествоСтавок = 0.5 
|           ТОГДА 1 
|       ИНАЧЕ 0 
|   КОНЕЦ) КАК РаботающиеНаПолставки
|ИЗ
|   ВТКадровыеДанныеСотрудников КАК КадровыеДанные
|ГДЕ
|   КадровыеДанные.Подразделение <> ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
|СГРУППИРОВАТЬ ПО
|   КадровыеДанные.Организация,
|   КадровыеДанные.Подразделение";

Запрос.УстановитьПараметр("ДатаОтчета", КонецДня(Объект.ПериодОтчета));
РезультатТаблица = Запрос.Выполнить().Выгрузить();

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

Решение 4. Использование механизма представлений в СКД

Если вы разрабатываете отчет на базе Системы компоновки данных (СКД), то лучшим решением будет использование виртуальных таблиц-представлений, таких как Представления_КадровыеДанныеСотрудников.

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


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

Что делать, если ставки всегда выводятся как «1»?

Иногда при тестировании запросов разработчики замечают, что поле КоличествоСтавок у всех сотрудников без исключения равно "1", даже если в кадровых приказах визуально указано "0.5" или "0.25".

Выясним причину этой проблемы: Дело в том, что в программе ЗУП 3.1 ведение дробных ставок является опциональной настройкой. Если эта опция выключена, программа принудительно записывает во все регистры значение "1".

Чтобы включить учет дробных ставок, выполните следующие шаги в режиме предприятия:

  1. Перейдите в раздел Настройки.
  2. Откройте пункт меню Кадровый учет.
  3. Установите флаг напротив опции "Используется работа по неполной ставке".

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

← На главную