Даты по графику. Возвращает даты, которые отличаются указанной даты ДатаОт на количество дней,
// Возвращает даты, которые отличаются указанной даты ДатаОт на количество дней,
// входящих в указанный график ГрафикРаботы.
//
// Параметры:
// ГрафикРаботы - СправочникСсылка.Календари - график, который необходимо использовать.
// ДатаОт - Дата - дата, от которой нужно рассчитать количество дней.
// МассивДней - Массив - количество дней (Число), на которые нужно увеличить дату начала.
// РассчитыватьСледующуюДатуОтПредыдущей - Булево - нужно ли рассчитывать следующую дату от предыдущей,
// или все даты рассчитываются от переданной даты.
// ВызыватьИсключение - Булево - если Истина, вызывается исключение в случае незаполненного графика.
//
// Возвращаемое значение:
// Массив, Неопределено - даты, увеличенные на количество дней, входящих в график ГрафикРаботы.
// Если график ГрафикРаботы не заполнен, и ВызыватьИсключение = Ложь, возвращается Неопределено.
//
Функция ДатыПоГрафику(Знач ГрафикРаботы, Знач ДатаОт, Знач МассивДней,
Знач РассчитыватьСледующуюДатуОтПредыдущей = Ложь, ВызыватьИсключение = Истина) Экспорт
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КалендарныеГрафики.СоздатьВТПриращениеДней(МенеджерВременныхТаблиц, МассивДней, РассчитыватьСледующуюДатуОтПредыдущей);
// Алгоритм работает следующим образом:
// Получаем количество включенных в график дней на дату отсчета.
// Для всех последующих годов получаем "смещение" количества дней в виде суммы количества дней предыдущих годов.
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| КалендарныеГрафики.Год,
| МАКСИМУМ(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) КАК ДнейВГрафике
|ПОМЕСТИТЬ ВТКоличествоДнейВГрафикеПоГодам
|ИЗ
| РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
|ГДЕ
| КалендарныеГрафики.ДатаГрафика >= &ДатаОт
| И КалендарныеГрафики.Календарь = &ГрафикРаботы
|
|СГРУППИРОВАТЬ ПО
| КалендарныеГрафики.Год
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| КоличествоДнейВГрафикеПоГодам.Год,
| СУММА(ЕСТЬNULL(КоличествоДнейПредыдущихГодов.ДнейВГрафике, 0)) КАК ДнейВГрафике
|ПОМЕСТИТЬ ВТКоличествоДнейСУчетомПредыдущихГодов
|ИЗ
| ВТКоличествоДнейВГрафикеПоГодам КАК КоличествоДнейВГрафикеПоГодам
| ЛЕВОЕ СОЕДИНЕНИЕ ВТКоличествоДнейВГрафикеПоГодам КАК КоличествоДнейПредыдущихГодов
| ПО (КоличествоДнейПредыдущихГодов.Год < КоличествоДнейВГрафикеПоГодам.Год)
|
|СГРУППИРОВАТЬ ПО
| КоличествоДнейВГрафикеПоГодам.Год
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| МИНИМУМ(КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода) КАК КоличествоДнейВГрафикеСНачалаГода
|ПОМЕСТИТЬ ВТКоличествоДнейВГрафикеНаДатуОтсчета
|ИЗ
| РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
|ГДЕ
| КалендарныеГрафики.ДатаГрафика >= &ДатаОт
| И КалендарныеГрафики.Год = ГОД(&ДатаОт)
| И КалендарныеГрафики.Календарь = &ГрафикРаботы
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПриращениеДней.ИндексСтроки,
| ЕСТЬNULL(КалендарныеГрафики.ДатаГрафика, НЕОПРЕДЕЛЕНО) КАК ДатаПоКалендарю
|ИЗ
| ВТПриращениеДней КАК ПриращениеДней
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТКоличествоДнейВГрафикеНаДатуОтсчета КАК КоличествоДнейВГрафикеНаДатуОтсчета
| ПО (ИСТИНА)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТКоличествоДнейСУчетомПредыдущихГодов КАК КоличествоДнейСУчетомПредыдущихГодов
| ПО (КоличествоДнейСУчетомПредыдущихГодов.Год = КалендарныеГрафики.Год)
| ПО (КалендарныеГрафики.КоличествоДнейВГрафикеСНачалаГода = КоличествоДнейВГрафикеНаДатуОтсчета.КоличествоДнейВГрафикеСНачалаГода - КоличествоДнейСУчетомПредыдущихГодов.ДнейВГрафике + ПриращениеДней.КоличествоДней)
| И (КалендарныеГрафики.ДатаГрафика >= &ДатаОт)
| И (КалендарныеГрафики.Календарь = &ГрафикРаботы)
| И (КалендарныеГрафики.ДеньВключенВГрафик)
|
|УПОРЯДОЧИТЬ ПО
| ПриращениеДней.ИндексСтроки";
Запрос.УстановитьПараметр("ДатаОт", НачалоДня(ДатаОт));
Запрос.УстановитьПараметр("ГрафикРаботы", ГрафикРаботы);
Выборка = Запрос.Выполнить().Выбрать();
МассивДат = Новый Массив;
Пока Выборка.Следующий() Цикл
Если Выборка.ДатаПоКалендарю = Неопределено Тогда
СообщениеОбОшибке = НСтр("ru = 'График работы «%1» не заполнен с даты %2 на указанное количество рабочих дней.'");
Если ВызыватьИсключение Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СообщениеОбОшибке, ГрафикРаботы, Формат(ДатаОт, "ДЛФ=D"));
Иначе
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
МассивДат.Добавить(Выборка.ДатаПоКалендарю);
КонецЦикла;
Возврат МассивДат;
КонецФункции
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
РасписанияРаботыНаПериод (БСП)
ШаблонТекстаЗапросаОпределенияБлижайшихДатПоГрафикуРаботы (БСП)
Сравнение плановых и фактических дней отпуска
ОбновитьГрафикиРаботыПоДаннымПроизводственныхКалендарей (БСП)
ЗаполнитьБлокируемыеОбъектыЗависимыеОтПроизводственныхКалендарей (БСП)