HelpF.pro

Разница между датами в рабочих днях, подсчет рабочих дней в 1С

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

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

Код, при вычислении определяет только по дню недели, викидывая выходные. Праздники не учитывает!

Код 1C v 8.х
 Функция РабочихДнейСДаты(НачДата,КолвоДней)  Экспорт
    Перем РабочихДней, ОбычныхДней, ДеньНедели;
    РабочихДней = 0; ОбычныхДней = 0;
    Пока РабочихДней < Число(КолвоДней) Цикл 
        ОбычныхДней = ОбычныхДней+ 1;          
       // определим день недели 
  ДеньНедели=ДеньНедели(НачДата+(ОбычныхДней*86400));           
       // если не выходной, то прошел еще один рабочий день 
        Если ДеньНедели < 6 Тогда
            РабочихДней=РабочихДней+1;
        КонецЕсли;
    КонецЦикла;
    
    Возврат (НачДата + (РабочихДней*86400));
КонецФункции


// Пример использования
ТриДняОтОбработки = РабочихДнейСДаты(нДатаОбработки,3);  
Если РабочаяДата>ТриДняОтОбработки Тогда
Предупреждение("Прошло больше 3-х дней после обработки заказа. Цены не актуальны!
|Отправьте заказ на новую обработку! ");
Иначе
// ... неки код
КонецЕсли;

В запросе, с использованием производственного календаря и учетом всех праздников:

Код 1C v 8.х
 ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата
ПОМЕСТИТЬ Даты
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря В(&ВходящиеДаты)
;


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


СГРУППИРОВАТЬ ПО
РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря,
Даты.Дата


ИМЕЮЩИЕ
МАКСИМУМ(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) = РегламентированныйПроизводственныйКалендарь1.ДатаКалендаря
И КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) =РабочихДней

Еще один вариант, в котором допустим, что:

1) Регистр сведений Календарь имеет структуру (Измерения={ДатаКалендаря}, Ресурсы={ВидДня}), а перечисление ВидыДня задано как {Рабочий, Предпразничный} и праздничные дни в календаре отсутствуют.

2) В документе Реализация заданы поля Дата и ОтсрочкаДней. Тогда:

Код 1C v 8.х
 Выбрать
Р.Ссылка, Р.Дата,
минимум(isnull(К.ДатаКалендаря, добавитькдате(Р.Дата, день, Р.ОтсрочкаДней))) как ДатаКредита
из Документ.Реализация как Р
левое соединение РегистрСведений.Календарь как К
по добавитькдате(Р.Дата, день, Р.ОтсрочкаДней) <= К.ДатаКалендаря
сгруппировать по
Р.Ссылка, Р.Дата

Собственно, если календарь содержит и праздничные дни, то можно добавить секцию ГДЕ, и там отобрать только рабочие дни. В секции ГДЕ можно отобрать и интересующий календарь, если ведется несколько календарей.


Опубликовано на сайте: https://HelpF.pro
Прямая ссылка: https://HelpF.pro/faq83/view/1727.html