Как рассчитать количество рабочих дней между датами в 1С?

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

Разберем частую задачу, с которой сталкиваются разработчики — подсчет количества рабочих дней между двумя заданными датами. При решении этой задачи часто возникает соблазн «изобрести велосипед», написав собственный алгоритм с перебором дней в цикле и проверкой каждого на принадлежность к выходным. Однако в современных типовых конфигурациях (таких как «Бухгалтерия предприятия 3.0», «Зарплата и управление персоналом 3» и других), построенных на базе Библиотеки стандартных подсистем (БСП), уже есть готовые инструменты. Рассмотрим их подробнее.

Использование готовых функций БСП

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

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


// Получаем ссылку на основной производственный календарь (например, РФ)
ГрафикРаботы = Справочники.ПроизводственныеКалендари.НайтиПоНаименованию("Российская Федерация");

// Вычисляем количество рабочих дней
КоличествоДней = КалендарныеГрафики.РазностьДатПоКалендарю(ГрафикРаботы, ДатаНачала, ДатаОкончания, Ложь);

Разберем по шагам параметры, которые принимает эта функция:

  1. ГрафикРаботы — ссылка на элемент справочника производственных календарей. Это важный параметр, поскольку в базе могут параллельно вестись не только федеральные, но и региональные календари со своими локальными праздниками.
  2. ДатаНачала и ДатаОкончания — период, за который необходимо выполнить расчет.
  3. ВызыватьИсключение — булево значение, отвечающее за поведение системы при незаполненном графике. Если передать значение Истина, то при отсутствии данных в календаре на указанный год программа выдаст ошибку. Если передать Ложь, функция просто вернет Неопределено, что позволит обработать эту ситуацию программно без прерывания работы кода.

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

Как рассчитать рабочие дни прямо в запросе

Методы общих модулей нельзя использовать напрямую внутри текстов запросов. Выясним, как быть, если количество рабочих дней между датами нужно вычислить динамически — например, для вывода в отчете на Системе Компоновки Данных (СКД) или в колонке динамического списка.

В этом случае задача решается через язык запросов с обращением к регистру сведений ДанныеПроизводственногоКалендаря. Проанализируем логику построения такого запроса:

  1. Выполняем левое соединение исходной таблицы с регистром ДанныеПроизводственногоКалендаря.
  2. В условии соединения (или в секции ГДЕ) указываем, что поле Дата из регистра должно находиться между нашей ДатаНачала и ДатаОкончания.
  3. Добавляем условие на реквизит ВидДня. Нас интересуют только значения перечисления, соответствующие рабочему времени: Рабочий или Предпраздничный.
  4. В секции выборки применяем агрегатную функцию КОЛИЧЕСТВО(ДанныеПроизводственногоКалендаря.Дата), которая подсчитает итоговое число подходящих записей.

Посмотрим на пример подобного запроса:


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

Дополнительные полезные функции модуля «КалендарныеГрафики»

Помимо расчета разности дат, в общем модуле КалендарныеГрафики есть и другие полезные методы. Рассмотрим некоторые из них:

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

← На главную