Как доработать отчет «Анализ неявок» в 1С:ЗУП 2.5 для расчета в рабочих часах вместо календарных дней

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

При работе в конфигурации «1С:Зарплата и Управление Персоналом 2.5» (ЗУП 2.5) пользователи часто сталкиваются с необходимостью кастомизации типовых отчетов. Один из классических примеров — перевод отчета по анализу неявок с календарных дней на рабочие часы. Типовой функционал рассчитывает именно календарные дни отклонений, однако для точного планирования и анализа занятости руководству требуются показатели в рабочих часах.

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

Этап 1. Разбор архитектуры данных ЗУП 2.5 для расчета времени

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

  1. Периоды неявок сотрудников: эти данные регистрируются в периодическом регистре сведений СостоянияРаботниковОрганизаций. В нем содержатся сведения о виде состояния (болезнь, отпуск, командировка и т.д.) и периодах действия этих состояний.
  2. Графики работы сотрудников: назначенные сотрудникам графики хранятся в периодическом регистре сведений РаботникиОрганизаций (ресурс ГрафикРаботы). Поскольку сотрудник может сменить график в середине месяца, нам необходимо получать актуальное значение на каждый день неявки.
  3. Плановые рабочие часы: сведения о количестве рабочих часов по конкретному графику на каждый день года содержатся в регистре сведений ГрафикиРаботыПоВидамВремени. Именно отсюда мы будем забирать плановые часы для видов времени «Явка» или «Ночные».

Этап 2. Учет индивидуальных графиков работы (важный нюанс)

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

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

Этап 3. Разработка оптимального запроса для СКД

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

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

Шаг 3.1. Получение периодов неявок сотрудников

Сначала выберем все записи о неявках сотрудников за интересующий нас период. Обратите внимание на обработку «открытых» больничных листов, у которых дата завершения может быть не заполнена (пустая дата):


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

Шаг 3.2. Развертка периодов неявок по дням

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


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

Шаг 3.3. Определение актуального графика работы сотрудника на каждый день неявки

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


ВЫБРАТЬ
    ДниНеявок.Сотрудник КАК Сотрудник,
    ДниНеявок.Состояние КАК Состояние,
    ДниНеявок.ДокументОснование КАК ДокументОснование,
    ДниНеявок.Дата КАК Дата,
    Работники.ГрафикРаботы КАК ГрафикРаботы
ПОМЕСТИТЬ ВТ_ДниСГрафиками
ИЗ
    ВТ_ДниНеявок КАК ДниНеявок
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК Работники
        ПО Работники.Сотрудник = ДниНеявок.Сотрудник
        И Работники.Период = (
            ВЫБРАТЬ МАКСИМУМ(Кадры.Период)
            ИЗ РегистрСведений.РаботникиОрганизаций КАК Кадры
            ГДЕ Кадры.Сотрудник = ДниНеявок.Sотрудник
                И Кадры.Период <= ДниНеявок.Дата
        )
;

Шаг 3.4. Соединение с регистром рабочего времени и расчет часов

На финальном этапе свяжем полученную таблицу дней с регистром ГрафикиРаботыПоВидамВремени. При этом учтем приоритет индивидуальных графиков над общими плановыми графиками, а также отфильтруем записи по значению «Явка» (чтобы выбрать именно стандартные рабочие часы):


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

Этап 4. Настройка ресурсов в СКД

После того как текст запроса успешно интегрирован в схему компоновки данных отчета «Анализ неявок», необходимо правильно настроить вкладку «Ресурсы»:

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

← На главную