Как программно сбросить расписание регламентных заданий к настройкам конфигуратора

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Почему стандартные метаданные возвращают Неопределено

Проанализируем техническую сторону вопроса. Многие начинающие разработчики пытаются получить доступ к расписанию через объект метаданных: Метаданные.РегламентныеЗадания.ИмяЗадания.Расписание. Однако на практике это свойство в режиме исполнения часто возвращает Неопределено. Это происходит потому, что в объекте метаданных хранится лишь «шаблон» расписания. Платформа 1С не предоставляет прямого программного метода «Сбросить к значениям по умолчанию» для объекта РегламентноеЗадание. Чтобы обойти это ограничение, нам придется использовать обходные пути.

Способ 1: Получение расписания через создание временного задания

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

Давайте разберем по шагам алгоритм действий:

  1. Находим метаданные нужного нам задания.
  2. Создаем временный объект регламентного задания.
  3. Копируем расписание из временного объекта в наше целевое (предопределенное) задание.
  4. Удаляем временный объект.

Посмотрим на пример кода, реализующий этот подход:


// Выбираем конкретное регламентное задание
МетаданныеЗадания = Метаданные.РегламентныеЗадания.ОчисткаНенужныхДанных;

// Создаем временное задание, чтобы считать дефолтное расписание
ВременноеЗадание = РегламентныеЗадания.СоздатьРегламентноеЗадание(МетаданныеЗадания);
ДефолтноеРасписание = ВременноеЗадание.Расписание;

// Находим наше основное предопределенное задание в базе
НайденоеЗадание = РегламентныеЗадания.НайтиПредопределенное(МетаданныеЗадания);

Если НайденоеЗадание <> Неопределено Тогда
    // Устанавливаем расписание из шаблона конфигуратора
    НайденоеЗадание.Расписание = ДефолтноеРасписание;
    НайденоеЗадание.Записать();
    
    // Не забываем удалить временный объект, чтобы он не висел в списке
    ВременноеЗадание.Удалить();
    Сообщить("Расписание задания " + МетаданныеЗадания.Имя + " успешно сброшено.");
КонецЕсли;

Способ 2: Синхронизация с эталонной базой через COM-соединение

Проанализируем ситуацию, когда у нас имеется множество однотипных информационных баз (например, филиальная сеть или облачный сервис), и нам нужно массово привести расписания к единому стандарту, настроенному в одной «эталонной» базе. В этом случае удобно использовать COM-соединение.

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

Рассмотрим пример кода для чтения данных из эталона:


// Устанавливаем соединение с базой-эталоном
COMСоединитель = Новый COMОбъект("V83.COMConnector");
СтрокаПодключения = "Srvr='ServerName';Ref='BaseName';Usr='Admin';Pwd='Pass';";
Соединение = COMСоединитель.Connect(СтрокаПодключения);

// Создаем таблицу для хранения эталонных настроек
СписокЗаданий = Новый ТаблицаЗначений;
СписокЗаданий.Колонки.Добавить("Метаданные");
СписокЗаданий.Колонки.Добавить("Расписание");
СписокЗаданий.Колонки.Добавить("Использование");

// Получаем список регламентных заданий из эталона
РегламентныеЭталон = Соединение.РегламентныеЗадания.ПолучитьРегламентныеЗадания();

Для Каждого ЗаданиеЭталон Из РегламентныеЭталон Цикл
    НоваяСтрока = СписокЗаданий.Добавить();
    НоваяСтрока.Метаданные = ЗаданиеЭталон.Метаданные.Представление();
    НоваяСтрока.Расписание = ЗаданиеЭталон.Расписание;
    НоваяСтрока.Использование = ЗаданиеЭталон.Use;
КонецЦикла;

После того как мы получили таблицу настроек, нам необходимо применить их к текущей базе. Важно помнить, что объект РасписаниеРегламентногоЗадания обладает множеством свойств, которые нужно перенести корректно.


// Применяем настройки к текущей ИБ
РегламентныеТекущейИБ = РегламентныеЗадания.ПолучитьРегламентныеЗадания();

Для Каждого ЗаданиеИБ Из РегламентныеТекущейИБ Цикл
    ПараметрыЭталона = СписокЗаданий.Найти(ЗаданиеИБ.Метаданные.Представление(), "Метаданные");
    
    Если ПараметрыЭталона <> Неопределено Тогда
        // Копируем ключевые свойства расписания
        ЗаданиеИБ.Расписание.BeginDate         = ПараметрыЭталона.Расписание.BeginDate;
        ЗаданиеИБ.Расписание.BeginTime         = ПараметрыЭталона.Расписание.BeginTime;
        ЗаданиеИБ.Расписание.RepeatPause       = ПараметрыЭталона.Расписание.RepeatPause;
        ЗаданиеИБ.Расписание.RepeatPeriodInDay = ПараметрыЭталона.Расписание.RepeatPeriodInDay;
        ЗаданиеИБ.Расписание.DaysRepeatPeriod  = ПараметрыЭталона.Расписание.DaysRepeatPeriod;
        // ... аналогично для остальных свойств (EndTime, WeeksPeriod и др.)
        
        ЗаданиеИБ.Использование = ПараметрыЭталона.Использование;
        ЗаданиеИБ.Записать();
    КонецЕсли;
КонецЦикла;

Использование возможностей БСП для сброса настроек

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), задача может быть решена штатными средствами подсистемы «Регламентные задания». В БСП реализованы механизмы хранения настроек и их обновления при изменении версии конфигурации.

Рассмотрим несколько полезных методов:

Важные нюансы при работе с расписанием

Проанализируем несколько критических моментов, которые стоит учитывать при написании своей обработки для сброса расписаний:

  1. Предопределенные задания: Помните, что предопределенные задания нельзя удалять методом Удалить(). Их можно только выключить (Использование = Ложь) или изменить их параметры.
  2. Права доступа: Для выполнения манипуляций с объектами РегламентноеЗадание программный код должен выполняться в привилегированном режиме или от имени пользователя с административными правами.
  3. Файловый и клиент-серверный варианты: В серверном варианте изменения применяются менеджером кластера практически мгновенно. В файловом варианте для вступления изменений в силу может потребоваться перезапуск сеанса, выполняющего роль планировщика заданий.
  4. Метод Записать(): Никогда не забывайте вызывать метод Записать() после изменения свойств объекта Расписание. Без этого вызова изменения останутся только в оперативной памяти вашего сеанса.

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

← На главную