В работе с 1С часто возникают задачи, требующие гибкой настройки автоматических процедур. Одна из таких задач — запуск регламентного задания не каждый день или раз в неделю, а в строго определенный интервал дат, например, для ежемесячной рассылки уведомлений с 20 по 23 число. Стандартный визуальный конструктор расписаний в режиме «1С:Предприятие» не предоставляет такой возможности напрямую. Давайте разберем несколько проверенных способов решения этой проблемы, от самых простых до более сложных и универсальных.
Это самый распространенный, гибкий и правильный с точки зрения архитектуры подход. Его суть заключается в том, что мы настраиваем регламентное задание на ежедневный запуск, но основную логику выполняем только при соблюдении определенных условий по дате. В остальные дни задание будет запускаться, но сразу же завершать свою работу, не создавая нагрузки на систему.
Рассмотрим по шагам, как это реализовать:
Посмотрим на пример кода, который предложил автор вопроса после получения совета. Он использовал строковые функции для получения дня, что не всегда надежно из-за региональных настроек формата даты.
// Первоначальный вариант из обсуждения
ДеньНедели = Лев(ТекущаяДата(), 2);
Если ДеньНедели = "20" ИЛИ
ДеньНедели = "21" ИЛИ
ДеньНедели = "22" ИЛИ
ДеньНедели = "23" Тогда
// ЗАПУСК РАССЫЛКИ
Иначе
Возврат;
КонецЕсли;
Мы можем улучшить этот код, сделав его более надежным и читаемым. Для получения номера дня из даты лучше использовать специальную функцию День(). Она всегда возвращает число, что избавляет от преобразований и потенциальных ошибок.
Более правильный и универсальный вариант кода:
Процедура ВыполнитьРассылкуУведомлений() Экспорт
// Получаем номер дня текущей даты
НомерДня = День(ТекущаяДата());
// Проверяем, входит ли день в наш интервал с 20 по 23
Если Не (НомерДня >= 20 И НомерДня <= 23) Тогда
// Если день не подходит, просто выходим из процедуры.
// Задание завершится, не выполнив основной логики.
Возврат;
КонецЕсли;
// --------------------------------------------------
// Если мы дошли до этого места, значит, сегодня нужный день.
// Здесь размещается основная логика вашей обработки.
// Например, формирование и отправка уведомлений.
// ...
// КОНЕЦ ОСНОВНОЙ ЛОГИКИ
// --------------------------------------------------
КонецПроцедуры
Преимущества этого метода:
Этот способ не требует внесения изменений в код и может подойти, если у вас нет доступа к конфигуратору или вы хотите избежать программирования. Идея проста: создать четыре отдельных, но идентичных регламентных задания, каждое из которых будет запускаться в один из нужных дней.
Разберем по шагам:
В результате у вас будет четыре задания, которые в совокупности обеспечат запуск обработки с 20 по 23 число каждого месяца.
Преимущества:
Недостатки:
Этот метод является развитием первого, но применяется в более сложных сценариях. Представим, что обработка, которую нужно запустить, зашифрована, поставляется сторонним разработчиком, и ее код нельзя изменять. Или, как в одном из вопросов на форуме, требуется еще более сложное расписание: по будням — в нерабочее время, а по выходным — круглосуточно.
В этом случае мы создаем свою собственную, простую внешнюю обработку-«обертку».
Проанализируем алгоритм:
ДеньНедели()).ВнешниеОбработки.Создать() и затем вызвать ее экспортную процедуру.Дополнительные отчеты и обработки.Пример кода для обработки-«обертки»:
Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения) Экспорт
// --- БЛОК ПРОВЕРКИ УСЛОВИЙ ---
// 1. Проверяем день месяца
НомерДня = День(ТекущаяДата());
Если Не (НомерДня >= 20 И НомерДня <= 23) Тогда
Возврат; // Не наш день, выходим
КонецЕсли;
// 2. Сложная проверка времени для будней и выходных
НомерДняНедели = ДеньНедели(ТекущаяДата());
ТекущееВремяСекунд = НачалоДня(ТекущаяДата()) - ТекущаяДата(); // Время в секундах от начала дня
ЭтоВыходной = (НомерДняНедели = 6 ИЛИ НомерДняНедели = 7);
Если Не ЭтоВыходной Тогда
// Это будний день. Запускаем только в нерабочее время.
// Например, до 9:00 (32400 сек) или после 18:00 (64800 сек)
Если ТекущееВремяСекунд > 32400 И ТекущееВремяСекунд < 64800 Тогда
Возврат; // Сейчас рабочее время, выходим
КонецЕсли;
КонецЕсли;
// В выходные дни проверка времени не нужна, запускаем круглосуточно.
// --- КОНЕЦ БЛОКА ПРОВЕРКИ УСЛОВИЙ ---
// Если все проверки пройдены, запускаем целевую обработку
// Имя нужной обработки нужно получить из ее идентификатора или найти в справочнике
ИмяЦелевойОбработки = "РассылкаУведомлений_Зашифрованная";
ПараметрыЗапуска = Новый Структура;
// Здесь можно передать параметры в целевую обработку, если она их поддерживает
Обработки.ВыполнитьОбработку(ИмяЦелевойОбработки, ИмяКоманды, ОбъектыНазначения, ПараметрыЗапуска);
КонецПроцедуры
Этот метод максимально гибок и позволяет реализовать расписание любой сложности, не трогая основной код целевой обработки.