Каталог решений - Поиск даты от текущей за вычетом выходных дней

Поиск даты от текущей за вычетом выходных дней

Поиск даты от текущей за вычетом выходных дней

В наличии

Простой способ поиска даты от текущей за вычетом выходных дней.

Категория:

Описание

Иногда возникает ситуация что нужно к текущей дате добавить несколько дней, и найти дату что наступит через эти дни. Нет проблем когда это нужно сделать без учета рабочих и выходных дней.

Вот здесь было найдено решение моей проблемы, только более завернутым путем, я предлагаю более простой способ для решения поиска нужной даты.

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

 

has been added to your cart:
Оформление заказа