Иногда возникает ситуация что нужно к текущей дате добавить несколько дней, и найти дату что наступит через эти дни. Нет проблем когда это нужно сделать без учета рабочих и выходных дней.
Вот здесь было найдено решение моей проблемы, только более завернутым путем, я предлагаю более простой способ для решения поиска нужной даты.
В данном примере приведен простой запрос который ищет день, который наступит через определенное количество дней за вычетом выходных дней. То есть допустим мне нужно добавить 5 дней, до текущей даты - 28.11.2018, данное число у меня приходится на среду, выходные дни - суббота и воскресенье. Фактически +5 дней это следующую рабочую неделю 5.12.2018.
- Фактически мы передаем в запрос дату от которой будем считать дни
- Ищем по номеру дня дату которая наступит через n - дней от даты среза, за вычетом выходных дней
Данный запрос помогает решить данную проблему:
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата,
РегламентированныйПроизводственныйКалендарь.ВидДня
ПОМЕСТИТЬ ВТ1
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= &ДатаСреза
И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата) КАК НомерДня,
ВТ1.Дата,
ВТ1.ВидДня
ИЗ
ВТ1 КАК ВТ1
ЛЕВОЕ СОЕДИНЕНИЕ ВТ1 КАК ВТ11
ПО ВТ1.Дата > ВТ11.Дата
СГРУППИРОВАТЬ ПО
ВТ1.Дата,
ВТ1.ВидДня
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата) = &НомерДня
УПОРЯДОЧИТЬ ПО
НомерДня
Сделал немножко апгрейд запроса для вожможности посчитать дни в любую сторону
ВЫБРАТЬ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК Дата,
РегламентированныйПроизводственныйКалендарь.ВидДня
ПОМЕСТИТЬ ВТ1
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
ВЫБОР
КОГДА &НомерДня > 0
ТОГДА РегламентированныйПроизводственныйКалендарь.ДатаКалендаря >= &ДатаСреза
ИНАЧЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря <= &ДатаСреза
КОНЕЦ
И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВЫБОР
КОГДА &НомерДня > 0
ТОГДА КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата)
ИНАЧЕ -КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ11.Дата)
КОНЕЦ КАК НомерДня,
ВТ1.Дата,
ВТ1.ВидДня
ПОМЕСТИТЬ ВТ2
ИЗ
ВТ1 КАК ВТ1
ЛЕВОЕ СОЕДИНЕНИЕ ВТ1 КАК ВТ11
ПО (ВЫБОР
КОГДА &НомерДня > 0
ТОГДА ВТ1.Дата > ВТ11.Дата
ИНАЧЕ ВТ1.Дата < ВТ11.Дата
КОНЕЦ)
СГРУППИРОВАТЬ ПО
ВТ1.Дата,
ВТ1.ВидДня
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ2.НомерДня КАК НомерДня,
ВТ2.Дата,
ВТ2.ВидДня
ИЗ
ВТ2 КАК ВТ2
ГДЕ
ВТ2.НомерДня = &НомерДня
УПОРЯДОЧИТЬ ПО
НомерДня
Что фактически изменил:
- в соответствии с переданым значением номера дня от даты среза считаются дни вперед или назад от текущей даты
- если номер дня со знаком минус считеам назад и наоборот
Также что хотелесь сказать знатокам мое решение не претендует на уникальность, если кому то поможет метод которым я решил свою проблему я буду очень рад
И в заверешение прикрепляю функцию для определения искоемого дня в стандартном модуле для УПП. (спасибо AnSk)
// Функция возвращает дату отстоящую на заданное количество рабочих дней от начальной в соответствии с
//регламентированным производственным календарем
//
//Параметры:
// ДатаНач - начальная дата
// ЧислоДней - количество рабочих дней, на которое искомая дата должна отстоять от начальной
//
Функция ОпределитьДату(ДатаНач, ЧислоДней) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНач", ДатаНач);
Запрос.УстановитьПараметр("ЧислоДней", ЧислоДней);
Запрос.УстановитьПараметр("РабочийДень", Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий);
Запрос.УстановитьПараметр("ПредпраздничныйДень", Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный);
Если ЧислоДней > 0 Тогда
Запрос.Текст = "
|ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ " + ЧислоДней + "
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
|ИЗ
| РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
|ГДЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря > &ДатаНач
| И (РегламентированныйПроизводственныйКалендарь.ВидДня = &РабочийДень
| ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = &ПредпраздничныйДень)
|УПОРЯДОЧИТЬ ПО
| ДатаКалендаря ВОЗР";
Иначе
ЧислоДней = -ЧислоДней;
Запрос.Текст = "
|ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ " + ЧислоДней + "
| РегламентированныйПроизводственныйКалендарь.ДатаКалендаря
|ИЗ
| РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
|ГДЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря < &ДатаНач
| И (РегламентированныйПроизводственныйКалендарь.ВидДня = &РабочийДень
| ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = &ПредпраздничныйДень)
|УПОРЯДОЧИТЬ ПО
| ДатаКалендаря УБЫВ
|";
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() = ЧислоДней Тогда
Пока Выборка.Следующий() Цикл
ТекДата = Выборка.ДатаКалендаря;
КонецЦикла;
Возврат ТекДата;
КонецЕсли;
Возврат Неопределено;
КонецФункции