Работа с регламентными заданиями в 1С:Предприятии часто требует не просто их наличия в конфигурации, но и возможности гибкого управления ими со стороны пользователя. Часто возникает задача «привязать» конкретное задание к настройкам в справочнике, чтобы пользователь мог открывать форму расписания прямо из карточки настройки, не заходя в системные консоли. Разберем подробно, как реализовать этот функционал, какие методы платформы использовать и как правильно организовать архитектуру таких связей.
Для начала рассмотрим ситуацию, когда в метаданных уже создано задание с установленным флагом Предопределенное. У таких объектов нет ссылки, как у элементов справочников, поэтому обращение к ним происходит через менеджер РегламентныеЗадания. Разберем способ получения объекта задания по его имени в метаданных.
Проанализируем пример кода, который позволяет найти такое задание и программно изменить его расписание:
// Поиск предопределенного задания по имени из метаданных
Задание = РегламентныеЗадания.НайтиПредопределенное(Метаданные.РегламентныеЗадания.ИмяВашегоЗадания);
Если Задание <> Неопределено Тогда
// Получаем текущее расписание задания
ТекущееРасписание = Задание.Расписание;
// Пример изменения параметров расписания
ТекущееРасписание.ПериодПовтораДней = 1;
ТекущееРасписание.ПериодПовтораВТечениеДня = 3600; // каждые 60 минут
// Записываем изменения в базу данных
Задание.Записать();
КонецЕсли;
Важно помнить, что метод НайтиПредопределенное возвращает конкретный экземпляр, созданный платформой автоматически. Если в базе данных по какой-то причине отсутствует экземпляр предопределенного задания (например, оно было удалено напрямую из таблиц СУБД), метод вернет Неопределено.
Одной из ключевых задач является предоставление пользователю удобного интерфейса для настройки времени запуска. Для этого в платформе предусмотрен специальный объект ДиалогРасписанияРегламентногоЗадания. Рассмотрим, как вызвать этот диалог из формы справочника.
Процесс состоит из двух этапов: получение расписания на сервере и вызов диалога на клиенте. Выясним, как это реализовать:
&НаСервере
Функция ПолучитьРасписаниеЗаданияНаСервере(УИДЗадания)
// Ищем задание по уникальному идентификатору
Задание = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(УИДЗадания);
Возврат Задание.Расписание;
КонецФункции
&НаКлиенте
Процедура НастроитьРасписание(Команда)
// Предположим, УИД хранится в реквизите объекта или получается динамически
ТекущееРасписание = ПолучитьРасписаниеЗаданияНаСервере(Объект.ИдентификаторРегламентногоЗадания);
Диалог = Новый ДиалогРасписанияРегламентногоЗадания(ТекущееРасписание);
// Используем оповещение для сохранения результата
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеНастройкиРасписания", ЭтотОбъект);
Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеНастройкиРасписания(НовоеРасписание, ДополнительныеПараметры) Экспорт
Если НовоеРасписание <> Неопределено Тогда
СохранитьРасписаниеНаСервере(НовоеРасписание);
КонецЕсли;
КонецПроцедуры
Такой подход позволяет пользователю менять настройки «по одной кнопке», не переходя в общие списки всех заданий информационной базы.
Если ваша задача подразумевает создание уникальных настроек для каждого элемента справочника (например, разные графики выгрузки для разных магазинов), использование одного предопределенного задания будет неудобным. В этом случае правильнее использовать регламентное задание как шаблон, а экземпляры создавать программно.
Разберем наиболее надежный метод связки через свойство Ключ. В качестве ключа мы будем использовать строковое представление уникального идентификатора (GUID) ссылки справочника. Проанализируем преимущества этого метода:
Рассмотрим пример реализации функции создания или обновления такого задания:
Процедура ОбновитьДанныеЗадания(СсылкаНаСправочник, Включить) Экспорт
УстановитьПривилегированныйРежим(Истина);
// Преобразуем УИД ссылки в строку для использования в качестве ключа
ИдентификаторЗадания = XMLСтрока(СсылкаНаСправочник.УникальныйИдентификатор());
// Пытаемся найти существующее задание
Отбор = Новый Структура;
Отбор.Вставить("Ключ", ИдентификаторЗадания);
Отбор.Вставить("Метаданные", Метаданные.РегламентныеЗадания.ВашеЗаданиеШаблон);
НайденныеЗадания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);
Если НайденныеЗадания.Количество() > 0 Тогда
РегламентноеЗадание = НайденныеЗадания[0];
Иначе
// Если не нашли — создаем новое по шаблону
РегламентноеЗадание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.ВашеЗаданиеШаблон);
РегламентноеЗадание.Ключ = ИдентификаторЗадания;
РегламентноеЗадание.Наименование = "Обработка для: " + СсылкаНаСправочник.Наименование;
// Передаем ссылку на справочник в параметры задания
ПараметрыЗапуска = Новый Массив;
ПараметрыЗапуска.Добавить(СсылкаНаСправочник);
РегламентноеЗадание.Параметры = ПараметрыЗапуска;
КонецЕсли;
РегламентноеЗадание.Использование = Включить;
РегламентноеЗадание.Записать();
КонецПроцедуры
При реализации данного функционала необходимо учитывать несколько критически важных моментов, с которыми сталкиваются разработчики 1С:
1. Привилегированный режим. Менеджер РегламентныеЗадания требует высоких прав доступа. Обычный пользователь не сможет прочитать или записать задание напрямую. Весь код по управлению заданиями должен располагаться в серверных модулях с установленным флагом Привилегированный.
2. Использование БСП. Если ваша конфигурация построена на Библиотеке стандартных подсистем (БСП), крайне рекомендуется использовать программный интерфейс модуля РегламентныеЗаданияСервер. Это обеспечит корректную регистрацию событий в журнале регистрации и интеграцию с типовыми формами мониторинга.
3. Передача параметров. Обратите внимание, что процедура, указанная в метаданных регламентного задания, должна иметь соответствующее количество экспортных параметров. Если вы передаете ссылку на справочник через РегламентноеЗадание.Параметры, убедитесь, что принимающая процедура в общем модуле определена как Процедура ВыполнитьОбработку(СсылкаНаНастройку) Экспорт.
4. Особенности в РИБ. Помните, что в распределенных информационных базах настройки расписания часто являются локальными. Если вы меняете расписание в «Центре», оно может не мигрировать в «Периферию» автоматически, так как состояние регламентных заданий привязано к конкретному серверу приложений.
Таким образом, мы выяснили, что для управления предопределенными заданиями лучше всего использовать метод НайтиПредопределенное, а для сложной логики с привязкой к данным — программное создание заданий с использованием Ключа на основе GUID объекта справочника.