Как правильно рассчитать периоды прогулов при наличии пересекающихся документов отсутствия и больничных в 1С?

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

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

Почему не стоит использовать сложные алгоритмы на встроенном языке?

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

  1. Трудозатратен в поддержке.
  2. Подвержен ошибкам «на единицу» (off-by-one error).
  3. Непроизводителен при большом объеме данных.

Платформа 1С обладает мощным механизмом Регистров Расчета, который был специально создан для учета пересекающихся периодов времени и автоматического вычисления Фактического периода действия.

Решение через использование виртуальной таблицы Фактического периода действия

Самый надежный способ получить данные о том, какие дни были отработаны или пропущены по конкретным видам начислений — использовать РегистрРасчета.Начисления.ФактическийПериодДействия. Этот механизм автоматически «нарезает» периоды с учетом вытеснения одних видов расчетов другими.

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


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    НачисленияФактическийПериодДействия.Сотрудник КАК Сотрудник,
    НачисленияФактическийПериодДействия.ВидРасчета КАК ВидРасчета,
    РАЗНОСТЬДАТ(НачисленияФактическийПериодДействия.ПериодДействияНачало, 
                 НачисленияФактическийПериодДействия.ПериодДействияКонец, ДЕНЬ) + 1 КАК ДнейФПД,
    НачисленияФактическийПериодДействия.ПериодДействияНачало КАК ПериодНачало,
    НачисленияФактическийПериодДействия.ПериодДействияКонец КАК ПериодКонец
ИЗ
    РегистрРасчета.Начисления.ФактическийПериодДействия(
        Организация = &Организация 
        И СторноТекущегоПериода = НЕОПРЕДЕЛЕНО
    ) КАК НачисленияФактическийПериодДействия
ГДЕ
    НачисленияФактическийПериодДействия.Сотрудник = &Сотрудник

Важное примечание: при использовании функции РАЗНОСТЬДАТ всегда добавляйте единицу, если вам нужно получить количество календарных дней в интервале включительно. В 1С разница между 1-м и 1-м числом дает 0, тогда как фактически это один день.

Особенности учета графиков работы

Если задача требует учитывать не просто календарные дни, а специфику графика работы (например, сменный график 2 через 2 или производственный календарь), одного РегистраРасчета может быть недостаточно. В этом случае мы должны объединить наши периоды с данными РегистраСведений.ГрафикиРаботыПоВидамВремени.

Алгоритм действий следующий:

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

Советы по работе с интервалами дат

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

Логика пересечения: НЕ (Конец1 < Начало2 ИЛИ Начало1 > Конец2). Эта простая логическая конструкция поможет вам эффективно отфильтровать документы в условии ГДЕ.

Также помните, что ВЫБОР КОГДА ... МЕЖДУ ... И ... ТОГДА — это базовый инструмент для проверки вхождения даты в интервал, но для пакетной обработки данных предпочтительнее использовать соединения (JOIN) временных таблиц.

Итоговая рекомендация

Для решения задачи прогулов в 1С:ЗУП:

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

← На главную