Разрабатывая некий функционал в 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( К. ДатаКалендаря, добавитькдате( Р. Дата, день, Р. ОтсрочкаДней) ) ) как ДатаКредита
из Документ. Реализация как Р
левое соединение РегистрСведений. Календарь как К
по добавитькдате( Р. Дата, день, Р. ОтсрочкаДней) < = К. ДатаКалендаря
сгруппировать по
Р. Ссылка, Р. Дата
Собственно, если календарь содержит и праздничные дни, то можно добавить секцию ГДЕ, и там отобрать только рабочие дни. В секции ГДЕ можно отобрать и интересующий календарь, если ведется несколько календарей.
Код 1C v 8.х
Запрос = Новый Запрос;
Запрос. Текст =
"ВЫБРАТЬ
| НАЧАЛОПЕРИОДА(Норма.ДатаКалендаря, МЕСЯЦ) КАК ПериодДействия,
| СотрудникиОрганизаций.Ссылка КАК Сотрудник,
| СотрудникиОрганизаций.ОбособленноеПодразделение КАК Организация,
| СУММА(ВЫБОР
| КОГДА Норма.ДатаКалендаря >= СотрудникиОрганизаций.ДатаПриемаНаРаботу
| И Норма.ДатаКалендаря <= СотрудникиОрганизаций.ДатаУвольнения
| ИЛИ Норма.ДатаКалендаря >= СотрудникиОрганизаций.ДатаПриемаНаРаботу
| И СотрудникиОрганизаций.ДатаУвольнения = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
| ТОГДА Норма.НормаВЧасах
| ИНАЧЕ 0
| КОНЕЦ) КАК НормаЧасов,
| СУММА(ВЫБОР
| КОГДА Норма.ДатаКалендаря >= СотрудникиОрганизаций.ДатаПриемаНаРаботу
| И Норма.ДатаКалендаря <= СотрудникиОрганизаций.ДатаУвольнения
| ИЛИ Норма.ДатаКалендаря >= СотрудникиОрганизаций.ДатаПриемаНаРаботу
| И СотрудникиОрганизаций.ДатаУвольнения = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
| ТОГДА Норма.НормаВДнях
| ИНАЧЕ 0
| КОНЕЦ) КАК НормаДней
|ИЗ
| (ВЫБРАТЬ
| СУММА(ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
| ТОГДА 8
| ИНАЧЕ ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
| ТОГДА 7
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ) КАК НормаВЧасах,
| Норма.ДатаКалендаря КАК ДатаКалендаря,
| ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
| ТОГДА 1
| ИНАЧЕ ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ КАК НормаВДнях
| ИЗ
| РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Норма
| ГДЕ
| Норма.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
|
| СГРУППИРОВАТЬ ПО
| Норма.ДатаКалендаря,
| ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
| ТОГДА 1
| ИНАЧЕ ВЫБОР
| КОГДА Норма.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ
| КОНЕЦ) КАК Норма,
| Справочник.СотрудникиОрганизаций КАК СотрудникиОрганизаций
|
|СГРУППИРОВАТЬ ПО
| НАЧАЛОПЕРИОДА(Норма.ДатаКалендаря, МЕСЯЦ),
| СотрудникиОрганизаций.Ссылка,
| СотрудникиОрганизаций.ОбособленноеПодразделение" ;
Запрос. УстановитьПараметр( "КонецПериода" , Дата( "31.05.2012 0:00:00" ) ) ;
Запрос. УстановитьПараметр( "НачалоПериода" , Дата( "01.05.2012 0:00:00" ) ) ;
Результат = Запрос. Выполнить( ) ;
Выборка = Результат. Выгрузить( ) ;
Для каждого СтрокаТЗ Из Выборка Цикл
КонецЦикла ;