|
Сдвиг даты с учетом производственного календаря | ☑ | ||
---|---|---|---|---|
0
apd123
04.10.14
✎
00:29
|
Понадобилось сделать функцию, которая вычисляет дату, отстоящую от начальной на заданное количество рабочих дней, с учетом производственного календаря, т.е. с учетом праздников и переносов выходных. Как ни странно, готового решения найти не удалось. Точнее, для типовых конфигураций, содержащих регламентированный производственный календарь вот тут v8: v8: Как к дате прибавить n дней исключая праздники? есть монструозная функция, но у меня довольно простая нетленка, поэтому прикручивать всю эту конструкцию не было смысла.
Итак, для начала понадобится собственно производственный календарь. Им будет обычный регистр сведений "Календарь" с одним измерением "Дата" и одним ресурсом "ТипДня", который является ссылкой на перечисление "ТипДняКалендаря", содержащее три значения: Рабочий, Выходной и Предпразничный. Последнее для вычисления смещения даты не понадобится, но может пригодиться в будущем для других целей. Заполняем календарь вот так Процедура ЗаполнитьКалендарьНаСервере() НаборЗаписей = РегистрыСведений.Календарь.СоздатьНаборЗаписей(); НаборЗаписей.Записать(); Для ТГод = 2009 по 2020 Цикл Для ТМесяц = 1 по 12 Цикл Для ТДень = 1 по 31 Цикл Попытка ТекущаяДата = Дата(ТГод,ТМесяц,ТДень); Исключение Продолжить; КонецПопытки; НовыйДень = РегистрыСведений.Календарь.СоздатьМенеджерЗаписи(); НовыйДень.Дата = ТекущаяДата; Если ДеньНедели(ТекущаяДата) = 6 или ДеньНедели(ТекущаяДата) = 7 тогда НовыйДень.ТипДня = Перечисления.ТипДняКалендаря.Выходной; Иначе НовыйДень.ТипДня = Перечисления.ТипДняКалендаря.Рабочий; КонецЕсли; НовыйДень.Записать(); КонецЦикла; КонецЦикла; КонецЦикла; КонецПроцедуры Годы, естественно, нужно подставить свои. После этого проходим руками по календарю и руками проставляем праздники, предпразничные дни и переносы выходных. Можно и не руками, я сделал импорт из экселя, показалось что так будет быстрее. Нужные даты можно взять например тут http://buh.ru/calendar/2015/ И сама функция, вычисляющая дату со сдвигом Функция РабДень(НачДача, Сдвиг) Экспорт Если Сдвиг >= 0 Тогда Сдвиг = Сдвиг + 1; Сортировка = "ВОЗР"; Отношение = ">="; Иначе Сдвиг = -Сдвиг; Сортировка = "УБЫВ"; Отношение = "<"; КонецЕсли; Запрос = Новый Запрос(" | ВЫБРАТЬ ПЕРВЫЕ " + Сдвиг + " Дата | ИЗ РегистрСведений.Календарь | ГДЕ Дата " + Отношение + " &ПервыйДень И ТипДня <> &Выходные | УПОРЯДОЧИТЬ ПО Дата " + Сортировка); Запрос.УстановитьПараметр("ПервыйДень", НачДача); Запрос.УстановитьПараметр("Выходные", Перечисления.ТипДняКалендаря.Выходной); Результат = Запрос.Выполнить().Выгрузить(); Возврат Результат.Получить(Результат.Количество()-1).Дата; КонецФункции |
|||
1
Fragster
гуру
04.10.14
✎
00:34
|
и что не работает?
|
|||
2
apd123
04.10.14
✎
00:37
|
(1) Работает. Делюсь для тех кто как я потратил день на поиски готового решения не в силах поверить что его нет.
|
|||
3
France
04.10.14
✎
00:38
|
Ожидает функциональности "монструозной" типовой.. сам делать не хочет - ожидает, что мистяне сделают
|
|||
4
apd123
04.10.14
✎
00:41
|
(3) Так ведь не монструозности, а необходимого минимума. И таки да, я удивлен что такой нужной штуки не нашлось.
|
|||
5
France
04.10.14
✎
00:53
|
(4) ну, в своих поделках я пользовал типовую.. ибо поделка сама была типовой))а та?, реально - создалось ощущение, что есть вопрс))на мисте секретами через кз делились)) зы.. или еще делятся?((
|
|||
6
apd123
04.10.14
✎
01:02
|
(5) Ох, да я тут новенький, про КЗ и не подумал. Скопипастил туда.
В любом случае тут принимается критика, советы и т.п. |
|||
7
Wobland
04.10.14
✎
02:18
|
(6) функция поломается при работе с датой, которой нет в календаре
|
|||
8
Wobland
04.10.14
✎
02:19
|
+(7) Результат.Получить(-1)
|
|||
9
apd123
06.10.14
✎
11:15
|
(7) Я думал над этим и пришел к выводу что она и должна ломаться, поскольку непонятно что нужно отдавать в таких случаях.
(8) При нулевом сдвиге отрабатывает как нужно. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |