Перед многими разработчиками встает задача автоматизировать создание документов по гибкому графику. Например, необходимо формировать наряды на техническое обслуживание (ТО) оборудования. При этом для каждого вида ТО или единицы оборудования расписание может быть своим. Создавать отдельное регламентное задание для каждого случая — неэффективно и неудобно в поддержке. Давайте разберем, как реализовать эту задачу элегантно и правильно.
Основная идея заключается в том, чтобы хранить настройки расписания непосредственно в элементе справочника (например, "Виды ТО"), а одно общее регламентное задание будет анализировать эти настройки и создавать документы, когда придет время.
В платформе 1С есть специальный объект для работы с расписаниями — РасписаниеРегламентногоЗадания. Он позволяет настроить любую периодичность: ежедневно, по определенным дням недели, раз в месяц и так далее. Однако этот объект нельзя напрямую записать в реквизит справочника. Чтобы обойти это ограничение, воспользуемся механизмом сериализации.
Сериализация — это процесс преобразования объекта в формат, удобный для хранения, в нашем случае — в строку XML. Эту строку уже можно сохранить в реквизите справочника.
РасписаниеXML, с типом "Строка неограниченной длины".РасписаниеРегламентногоЗадания в XML-строку и записать в наш реквизит.Посмотрим на пример кода для сохранения расписания:
// Предположим, у нас есть настроенный объект РасписаниеТО
// типа РасписаниеРегламентногоЗадания
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Сериализуем объект РасписаниеТО в XML
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, РасписаниеТО);
// Получаем XML-строку и сохраняем ее в реквизит
ОбъектСправочника.РасписаниеXML = ЗаписьXML.Закрыть();
ОбъектСправочника.Записать();
Теперь создадим одно регламентное задание, которое будет запускаться с определенной периодичностью, например, раз в день. Его задача — проверить все расписания из нашего справочника и создать документы, если пришло время.
Рассмотрим логику работы этого задания:
РасписаниеXML.РасписаниеXML.РасписаниеРегламентногоЗадания.ТребуетсяВыполнение(<Дата>), чтобы проверить, нужно ли выполнять ТО на текущую дату.ТребуетсяВыполнение() вернул Истина, то программно создаем новый документ "Наряд", заполняя его данными из текущего элемента справочника (оборудование, вид ТО и т.д.).Проанализируем, как может выглядеть процедура, выполняемая в регламентном задании.
Процедура СоздатьНарядыПоРасписанию() Экспорт
ТекущаяДата = ТекущаяДата();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыТО.Ссылка,
| ВидыТО.РасписаниеXML
|ИЗ
| Справочник.ВидыТО КАК ВидыТО
|ГДЕ
| ВидыТО.РасписаниеXML <> """"";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Пропускаем, если реквизит пустой
Если НЕ ЗначениеЗаполнено(Выборка.РасписаниеXML) Тогда
Продолжить;
КонецЕсли;
// Десериализуем расписание из строки
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Выборка.РасписаниеXML);
Попытка
Расписание = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Исключение
// Записать в журнал ошибку чтения XML
Продолжить;
КонецПопытки;
// Проверяем, нужно ли выполнять задание сегодня
Если Расписание.ТребуетсяВыполнение(ТекущаяДата) Тогда
// Создаем документ "Наряд"
НовыйНаряд = Документы.Наряд.СоздатьДокумент();
НовыйНаряд.Дата = ТекущаяДата;
НовыйНаряд.ВидТО = Выборка.Ссылка;
// ... заполняем остальные реквизиты ...
Попытка
НовыйНаряд.Записать();
Исключение
// Записать в журнал ошибку создания документа
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот метод является стандартной практикой для решения подобных задач и имеет ряд весомых плюсов:
Важно помнить, что в файловом варианте работы базы данных для выполнения регламентных заданий по расписанию требуется постоянно запущенный ("дежурный") сеанс 1С. В клиент-серверном варианте задания выполняются автоматически на сервере 1С:Предприятия.