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