Книга знаний

1С:Предприятие / Приемы программирования / Встроенный язык

Сдвиг даты с учетом производственного календаря

Вычисление даты, отстоящей от начальной на заданное количество рабочих дней, с учетом производственного календаря, т.е. с учетом праздников и переносов выходных.Автор статьи: apd123 | Редакторы:
Последняя редакция №2 от 04.10.14 | История
URL: http://kb.mista.ru/article.php?id=933

Ключевые слова: сдвиг даты, производственный календарь, праздники, выходные


Понадобилось сделать функцию, которая вычисляет дату, отстоящую от начальной на заданное количество рабочих дней, с
учетом
производственного календаря, т.е. с учетом праздников и переносов выходных. Как ни странно, готового решения найти не
удалось. Точнее,
для типовых конфигураций, содержащих регламентированный производственный календарь вот тут
v8: v8: Как к дате прибавить n дней исключая праздники? есть монструозная функция, но у меня довольно простая нетленка, поэтому
прикручивать всю эту конструкцию не было смысла.

Итак, для начала понадобится собственно производственный календарь. Им будет обычный регистр сведений "Календарь" с
одним измерением
"Дата" и одним ресурсом "ТипДня", который является ссылкой на перечисление "ТипДняКалендаря", содержащее три
значения: Рабочий,
Выходной и Предпразничный. Последнее для вычисления смещения даты не понадобится, но может пригодиться в будущем
для других целей.

Заполняем календарь вот так

Процедура ЗаполнитьКалендарьНаСервере()

   НаборЗаписей = РегистрыСведений.Календарь.СоздатьНаборЗаписей();
   НаборЗаписей.Записать();
       
   Для ТГод = 2009 по 2020 Цикл
       Для ТМесяц = 1 по 12 Цикл
           Для ТДень = 1 по 31 Цикл                
               Попытка            
                   ТекущаяДата = Дата(ТГод,ТМесяц,ТДень);    
               Исключение
                   Продолжить;
               КонецПопытки;            
           
               НовыйДень = РегистрыСведений.Календарь.СоздатьМенеджерЗаписи();
               НовыйДень.Дата = ТекущаяДата;
               Если ДеньНедели(ТекущаяДата) = 6 или ДеньНедели(ТекущаяДата) = 7 тогда
                   НовыйДень.ТипДня = Перечисления.ТипДняКалендаря.Выходной;
               Иначе
                   НовыйДень.ТипДня = Перечисления.ТипДняКалендаря.Рабочий;
               КонецЕсли;
               НовыйДень.Записать();
           КонецЦикла;
       КонецЦикла;
   КонецЦикла;
КонецПроцедуры


Годы, естественно, нужно подставить свои.

После этого проходим руками по календарю и руками проставляем праздники, предпразничные дни и переносы выходных.
Можно и не
руками, я сделал импорт из экселя, показалось что так будет быстрее. Нужные даты можно взять например тут
http://buh.ru/calendar/2015/

И сама функция, вычисляющая дату со сдвигом
Функция РабДень(НачДача, Сдвиг) Экспорт

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

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика