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