В практике разработки на платформе 1С:Предприятие 8.3 часто возникает необходимость программной проверки расписания. Например, когда мы создаем собственную очередь заданий или механизм обслуживания, который должен запускаться строго по графику, заданному пользователем. Основным инструментом для этого является метод ТребуетсяВыполнение() объекта РасписаниеРегламентногоЗадания. Однако этот метод обладает специфической логикой, которая может привести к неожиданным результатам: программа считает, что задание запускать не нужно, хотя визуально дата кажется подходящей. В данной статье мы подробно разберем, как работает этот метод, почему возникают логические конфликты и как их устранить.
Для начала проанализируем синтаксис метода ТребуетсяВыполнение(). Он предназначен для проверки соответствия конкретного момента времени заданному шаблону расписания.
Синтаксис вызова выглядит следующим образом:
Результат = Расписание.ТребуетсяВыполнение(ДатаДляПроверки, ДатаНачалаПоследнегоЗапуска, ДатаЗавершенияПоследнегоЗапуска);
Рассмотрим параметры подробнее:
Дата. Это момент времени, на который мы хотим «примерить» расписание. Если параметр не указан, система берет текущее время сервера. Важно помнить, что этот параметр включает в себя и время (часы, минуты, секунды).Ложь.Разберем ситуацию, с которой столкнулся автор темы. В его расписании были установлены одновременно два условия:
Проанализируем поведение системы в этом случае. Большинство разработчиков интуитивно полагают, что система сработает по правилу «ИЛИ» (либо 2-го числа, либо в третью неделю). Однако платформа 1С интерпретирует это как строгое логическое объединение (И). Это означает, что метод ТребуетсяВыполнение() вернет Истина только в том случае, если 2-е число месяца одновременно окажется днем, принадлежащим третьей неделе этого месяца.
Как мы понимаем, календарно это практически невозможно, так как 2-е число всегда попадает в первую неделю (или самое начало второй). Именно поэтому метод возвращал Ложь на 2-е ноября, но мог вернуть Истина для 15-го числа, если настройки были изменены. В исходном примере 15 ноября 2021 года было третьим понедельником месяца, и если бы условие по числу месяца было «15», задание бы сработало.
Выясним причину некорректного поведения и исправим настройки. Для того чтобы расписание работало предсказуемо, необходимо следовать алгоритму:
Шаг 1. Очистка конфликтующих параметров.
Если вам нужно, чтобы задание выполнялось строго по конкретным числам месяца (например, 2-го и 15-го числа), убедитесь, что свойство ДеньНеделиВМесяце (или соответствующий реквизит в диалоге настройки) установлено в значение 0 (не определено). Это отключит проверку номера недели и оставит только проверку даты.
Шаг 2. Проверка времени запуска.
Метод ТребуетсяВыполнение крайне чувствителен к составляющей времени в параметре ДатаДляПроверки. Проанализируем пример кода:
// Неправильно: время 00:00:00 может быть раньше времени начала в расписании
ДеньПроверки = НачалоДня(ТекущаяДата());
Если РасписаниеЗадания.ТребуетсяВыполнение(ДеньПроверки) Тогда
// Код выполнения
КонецЕсли;
// Правильно: передаем конец дня или конкретное расчетное время
ДеньПроверки = КонецДня(ТекущаяДата());
Если РасписаниеЗадания.ТребуетсяВыполнение(ДеньПроверки) Тогда
// Код выполнения
КонецЕсли;
Если в расписании указано время начала 09:00:00, то при передаче даты со временем 00:00:00 метод вернет Ложь, так как в этот момент времени «срок еще не подошел».
Рассмотрим еще несколько важных факторов, влияющих на результат выполнения метода:
1. Отрицательные значения недель.
В объекте РасписаниеРегламентногоЗадания свойство ДеньНеделиВМесяце может принимать отрицательные значения. Например, значение -1 означает «последний день недели в месяце» (последняя пятница месяца). Если вы случайно установили такое значение, проверка на обычные даты будет давать Ложь.
2. Игнорирование истории запусков.
Если вы хотите проверить, подходит ли дата под шаблон расписания в принципе (без учета того, запускалось ли задание ранее), передавайте во второй и третий параметры пустую дату:
НужноЛи = Расписание.ТребуетсяВыполнение(ПроверяемаяДата, '00010101', '00010101');
Это заставит метод игнорировать историю и проверять только календарное соответствие.
3. Влияние часовых поясов.
Проанализируем ситуацию с серверным временем. Метод работает в контексте текущего сеанса. Если сервер находится в одном часовом поясе, а ДатаДляПроверки сформирована в другом (без приведения к единому стандарту), возможны ошибки «смещения» на сутки. Всегда приводите проверяемые даты к времени сервера.
Для корректной работы метода ТребуетсяВыполнение() необходимо:
ДатаДляПроверки содержала время, которое больше или равно времени начала, указанному в расписании.Соблюдение этих правил позволит создавать надежные механизмы планирования в ваших конфигурациях 1С.