Как настроить запуск регламентного задания в определенные дни месяца, например с 20 по 23 число?

Программист IT и автоматизация бизнеса
← На главную

В работе с 1С часто возникают задачи, требующие гибкой настройки автоматических процедур. Одна из таких задач — запуск регламентного задания не каждый день или раз в неделю, а в строго определенный интервал дат, например, для ежемесячной рассылки уведомлений с 20 по 23 число. Стандартный визуальный конструктор расписаний в режиме «1С:Предприятие» не предоставляет такой возможности напрямую. Давайте разберем несколько проверенных способов решения этой проблемы, от самых простых до более сложных и универсальных.

Решение 1: Проверка даты внутри кода обработки (рекомендуемый способ)

Это самый распространенный, гибкий и правильный с точки зрения архитектуры подход. Его суть заключается в том, что мы настраиваем регламентное задание на ежедневный запуск, но основную логику выполняем только при соблюдении определенных условий по дате. В остальные дни задание будет запускаться, но сразу же завершать свою работу, не создавая нагрузки на систему.

Рассмотрим по шагам, как это реализовать:

  1. Откройте консоль регламентных заданий и настройте расписание, а менеджер внешних обработок поможет вам быстро протестировать запуск.
  2. Перейдите в конфигуратор и откройте модуль обработки, которая выполняется по этому расписанию.
  3. В самом начале исполняемой процедуры добавьте проверку текущей даты. Если дата не входит в нужный нам интервал (с 20 по 23 число), процедура должна быть прервана.

Посмотрим на пример кода, который предложил автор вопроса после получения совета. Он использовал строковые функции для получения дня, что не всегда надежно из-за региональных настроек формата даты.


// Первоначальный вариант из обсуждения
ДеньНедели = Лев(ТекущаяДата(), 2); 
Если ДеньНедели = "20" ИЛИ
     ДеньНедели = "21" ИЛИ
     ДеньНедели = "22" ИЛИ
     ДеньНедели = "23" Тогда
     // ЗАПУСК РАССЫЛКИ
Иначе
     Возврат;
КонецЕсли;

Мы можем улучшить этот код, сделав его более надежным и читаемым. Для получения номера дня из даты лучше использовать специальную функцию День(). Она всегда возвращает число, что избавляет от преобразований и потенциальных ошибок.

Более правильный и универсальный вариант кода:


Процедура ВыполнитьРассылкуУведомлений() Экспорт

    // Получаем номер дня текущей даты
    НомерДня = День(ТекущаяДата());
    
    // Проверяем, входит ли день в наш интервал с 20 по 23
    Если Не (НомерДня >= 20 И НомерДня <= 23) Тогда
        // Если день не подходит, просто выходим из процедуры.
        // Задание завершится, не выполнив основной логики.
        Возврат;
    КонецЕсли;
    
    // --------------------------------------------------
    // Если мы дошли до этого места, значит, сегодня нужный день.
    // Здесь размещается основная логика вашей обработки.
    // Например, формирование и отправка уведомлений.
    // ...
    // КОНЕЦ ОСНОВНОЙ ЛОГИКИ
    // --------------------------------------------------

КонецПроцедуры

Преимущества этого метода:

Решение 2: Создание нескольких регламентных заданий

Этот способ не требует внесения изменений в код и может подойти, если у вас нет доступа к конфигуратору или вы хотите избежать программирования. Идея проста: создать четыре отдельных, но идентичных регламентных задания, каждое из которых будет запускаться в один из нужных дней.

Разберем по шагам:

  1. Перейдите в раздел администрирования регламентных и фоновых заданий.
  2. Создайте новое регламентное задание для вашей обработки.
  3. Перейдите к настройке расписания. На вкладке "Месячные" укажите день месяца: 20. Убедитесь, что все месяцы выбраны.
  4. Сохраните это задание, дав ему понятное имя, например, "Рассылка уведомлений (20-е число)".
  5. Скопируйте созданное задание и измените в его расписании день месяца на 21. Измените имя на "Рассылка уведомлений (21-е число)".
  6. Повторите эту операцию для 22-го и 23-го числа.

В результате у вас будет четыре задания, которые в совокупности обеспечат запуск обработки с 20 по 23 число каждого месяца.

Преимущества:

Недостатки:

Решение 3: Использование обработки-обертки («запускателя»)

Этот метод является развитием первого, но применяется в более сложных сценариях. Представим, что обработка, которую нужно запустить, зашифрована, поставляется сторонним разработчиком, и ее код нельзя изменять. Или, как в одном из вопросов на форуме, требуется еще более сложное расписание: по будням — в нерабочее время, а по выходным — круглосуточно.

В этом случае мы создаем свою собственную, простую внешнюю обработку-«обертку».

Проанализируем алгоритм:

  1. Создайте новую внешнюю обработку (назовем ее "Запускатель рассылки").
  2. В модуле этой обработки реализуйте всю сложную логику проверки условий:
    • Проверка дня месяца (с 20 по 23).
    • Проверка дня недели (ДеньНедели()).
    • Проверка текущего времени.
    • Любые другие бизнес-условия.
  3. Если все условия выполняются, ваша обработка-«обертка» должна программно запустить целевую (зашифрованную) обработку. Для этого можно использовать объект ВнешниеОбработки.Создать() и затем вызвать ее экспортную процедуру.
  4. Добавьте вашу обработку-"запускатель" в справочник Дополнительные отчеты и обработки.
  5. Создайте регламентное задание, которое будет запускать вашу обработку-"запускатель" по простому расписанию (например, каждый час или каждые 15 минут).

Пример кода для обработки-«обертки»:


Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения) Экспорт

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

    // --- КОНЕЦ БЛОКА ПРОВЕРКИ УСЛОВИЙ ---
    
    // Если все проверки пройдены, запускаем целевую обработку
    // Имя нужной обработки нужно получить из ее идентификатора или найти в справочнике
    ИмяЦелевойОбработки = "РассылкаУведомлений_Зашифрованная";
    
    ПараметрыЗапуска = Новый Структура;
    // Здесь можно передать параметры в целевую обработку, если она их поддерживает
    
    Обработки.ВыполнитьОбработку(ИмяЦелевойОбработки, ИмяКоманды, ОбъектыНазначения, ПараметрыЗапуска);

КонецПроцедуры

Этот метод максимально гибок и позволяет реализовать расписание любой сложности, не трогая основной код целевой обработки.

← На главную