Как прибавить X рабочих дней к исходной дате в 1С?

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

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

Понимание задачи и выбор метода решения

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

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

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

Рассмотрим алгоритм действий по шагам:

  1. Определяем начальную дату, от которой планируем вести отсчет.
  2. Формируем запрос к регистру сведений, чтобы получить список предстоящих рабочих дней.
  3. Ограничиваем выборку количеством необходимых рабочих дней, используя конструкцию ПЕРВЫЕ.
  4. Из полученного списка выбираем дату последнего рабочего дня, которая и будет являться искомым результатом.

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


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

Оптимизация расчета

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


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

Важные замечания по разработке

При реализации данного функционала обратите внимание на следующие рекомендации:

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

← На главную