ДатыБлижайшихРабочихДней (БСП)

Автор: 1С
ОбщийМодуль.КалендарныеГрафики
БСП

Даты ближайших рабочих дней. Определяет для каждой даты дату ближайшего к ней рабочего дня.

// Определяет для каждой даты дату ближайшего к ней рабочего дня.
//
//	Параметры:
//	  График	- СправочникСсылка.Календари, СправочникСсылка.ПроизводственныеКалендари - график или 
//                    производственный календарь, который необходимо использовать для расчета.
//	  НачальныеДаты 				- Массив - массив дат (Дата).
//	  ПолучатьПредшествующие		- Булево - способ получения ближайшей даты:
//										если Истина - определяются рабочие даты, предшествующие переданным в параметре НачальныеДаты, 
//										если Ложь - получаются даты не ранее начальной даты.
//	  ВызыватьИсключение - Булево - если Истина, вызвать исключение в случае незаполненного графика.
//	  ИгнорироватьНезаполненностьГрафика - Булево - если Истина, то в любом случае будет возвращено соответствие. 
//										Начальные даты, для которых не будет значений из-за незаполненности графика, включены не будут.
//
//	Возвращаемое значение:
//	  Соответствие, Неопределено - соответствие, где ключ - дата из переданного массива, 
//									значение - ближайшая к ней рабочая дата (если передана рабочая дата, то она же и возвращается).
//									Если выбранный график не заполнен, и ВызыватьИсключение = Ложь, возвращается Неопределено.
//
Функция ДатыБлижайшихРабочихДней(График, НачальныеДаты, ПолучатьПредшествующие = Ложь, ВызыватьИсключение = Истина, 
	ИгнорироватьНезаполненностьГрафика = Ложь) Экспорт
	
	Если Не ЗначениеЗаполнено(График) Тогда
		Если ВызыватьИсключение Тогда
			ВызватьИсключение НСтр("ru = 'Не указан график работы или производственный календарь.'");
		КонецЕсли;
		Возврат Неопределено;
	КонецЕсли;
	
	ТекстЗапросаВТ = "";
	ПерваяЧасть = Истина;
	Для Каждого НачальнаяДата Из НачальныеДаты Цикл
		Если Не ЗначениеЗаполнено(НачальнаяДата) Тогда
			Продолжить;
		КонецЕсли;
		Если Не ПерваяЧасть Тогда
			ТекстЗапросаВТ = ТекстЗапросаВТ + "
			|ОБЪЕДИНИТЬ ВСЕ
			|";
		КонецЕсли;
		ТекстЗапросаВТ = ТекстЗапросаВТ + "
		|ВЫБРАТЬ
		|	ДАТАВРЕМЯ(" + Формат(НачальнаяДата, "ДФ=гггг,ММ,дд") + ")";
		Если ПерваяЧасть Тогда
			ТекстЗапросаВТ = ТекстЗапросаВТ + " КАК Дата 
			|ПОМЕСТИТЬ НачальныеДаты
			|";
		КонецЕсли;
		ПерваяЧасть = Ложь;
	КонецЦикла;

	Если ПустаяСтрока(ТекстЗапросаВТ) Тогда
		Возврат Новый Соответствие;
	КонецЕсли;
	
	Запрос = Новый Запрос(ТекстЗапросаВТ);
	Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	Запрос.Выполнить();
	
	Если ТипЗнч(График) = Тип("СправочникСсылка.ПроизводственныеКалендари") Тогда
		ТекстЗапроса = 
		"ВЫБРАТЬ
		|	НачальныеДаты.Дата,
		|	%Функция%(ДатыКалендаря.Дата) КАК БлижайшаяДата
		|ИЗ
		|	НачальныеДаты КАК НачальныеДаты
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДатыКалендаря
		|		ПО (ДатыКалендаря.Дата %ЗнакУсловия% НачальныеДаты.Дата)
		|			И (ДатыКалендаря.ПроизводственныйКалендарь = &График)
		|			И (ДатыКалендаря.ВидДня В (
		|			ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий), 
		|			ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
		|			))
		|
		|СГРУППИРОВАТЬ ПО
		|	НачальныеДаты.Дата";
	Иначе
		// По графику работы
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ГрафикиРаботы") Тогда
			МодульГрафикиРаботы = ОбщегоНазначения.ОбщийМодуль("ГрафикиРаботы");
			ТекстЗапроса = МодульГрафикиРаботы.ШаблонТекстаЗапросаОпределенияБлижайшихДатПоГрафикуРаботы();
		КонецЕсли;
	КонецЕсли;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "%Функция%", 				?(ПолучатьПредшествующие, "МАКСИМУМ", "МИНИМУМ"));
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "%ЗнакУсловия%", 			?(ПолучатьПредшествующие, "<=", ">="));
	
	Запрос.Текст = ТекстЗапроса;
	Запрос.УстановитьПараметр("График", График);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	ДатыРабочихДней = Новый Соответствие;
	Пока Выборка.Следующий() Цикл
		Если ЗначениеЗаполнено(Выборка.БлижайшаяДата) Тогда
			ДатыРабочихДней.Вставить(Выборка.Дата, Выборка.БлижайшаяДата);
		Иначе 
			Если ИгнорироватьНезаполненностьГрафика Тогда
				Продолжить;
			КонецЕсли;
			Если ВызыватьИсключение Тогда
				ТекстСообщения = НСтр("ru = 'Невозможно определить ближайшую рабочую дату для даты %1, возможно, график работы не заполнен.'");
				ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстСообщения, Формат(Выборка.Дата, "ДЛФ=D"));
			Иначе
				Возврат Неопределено;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ДатыРабочихДней;
	
КонецФункции

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

ПолучитьБлижайшуюДатуСобытияПоРасписанию (БСП)

ОтключитьНапоминание (БСП)

ДатыПоГрафику (БСП)

ДатаПоГрафику (БСП)

ДатыПоКалендарю (БСП)

ДатаПоКалендарю (БСП)

ШаблонТекстаЗапросаОпределенияБлижайшихДатПоГрафикуРаботы (БСП)

ДатаСледующегоАвтоматическогоКопирования (БСП)

РазностьДатПоКалендарю (БСП)

Синтакс-помощник БСП с нейросетевым ассистентом