Как в 1С автоматически создавать документы по расписанию, которое хранится в справочнике?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

Перед многими разработчиками встает задача автоматизировать создание документов по гибкому графику. Например, необходимо формировать наряды на техническое обслуживание (ТО) оборудования. При этом для каждого вида ТО или единицы оборудования расписание может быть своим. Создавать отдельное регламентное задание для каждого случая — неэффективно и неудобно в поддержке. Давайте разберем, как реализовать эту задачу элегантно и правильно.

Основная идея заключается в том, чтобы хранить настройки расписания непосредственно в элементе справочника (например, "Виды ТО"), а одно общее регламентное задание будет анализировать эти настройки и создавать документы, когда придет время.

Шаг 1. Хранение расписания в справочнике

В платформе 1С есть специальный объект для работы с расписаниями — РасписаниеРегламентногоЗадания. Он позволяет настроить любую периодичность: ежедневно, по определенным дням недели, раз в месяц и так далее. Однако этот объект нельзя напрямую записать в реквизит справочника. Чтобы обойти это ограничение, воспользуемся механизмом сериализации.

Сериализация — это процесс преобразования объекта в формат, удобный для хранения, в нашем случае — в строку XML. Эту строку уже можно сохранить в реквизите справочника.

  1. Создайте в вашем справочнике (например, "ВидыТО") новый реквизит, назовем его РасписаниеXML, с типом "Строка неограниченной длины".
  2. В форме элемента этого справочника нужно предоставить пользователю интерфейс для настройки расписания. При сохранении настроек расписания в коде необходимо будет преобразовать объект РасписаниеРегламентногоЗадания в XML-строку и записать в наш реквизит.

Посмотрим на пример кода для сохранения расписания:


// Предположим, у нас есть настроенный объект РасписаниеТО
// типа РасписаниеРегламентногоЗадания

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

// Сериализуем объект РасписаниеТО в XML
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, РасписаниеТО);

// Получаем XML-строку и сохраняем ее в реквизит
ОбъектСправочника.РасписаниеXML = ЗаписьXML.Закрыть();
ОбъектСправочника.Записать();

Шаг 2. Создание общего регламентного задания

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

Рассмотрим логику работы этого задания:

  1. Запуск. Задание стартует по своему собственному расписанию (например, каждое утро в 5:00).
  2. Получение данных. Задание делает запрос к справочнику "ВидыТО" и выбирает все элементы, у которых заполнено поле РасписаниеXML.
  3. Анализ расписаний. В цикле обходим полученные элементы справочника. Для каждого элемента выполняем обратный процесс — десериализацию.
    • Считываем строку из реквизита РасписаниеXML.
    • Преобразуем (десериализуем) эту строку обратно в объект РасписаниеРегламентногоЗадания.
    • Используем метод объекта ТребуетсяВыполнение(<Дата>), чтобы проверить, нужно ли выполнять ТО на текущую дату.
  4. Создание документов. Если метод ТребуетсяВыполнение() вернул Истина, то программно создаем новый документ "Наряд", заполняя его данными из текущего элемента справочника (оборудование, вид ТО и т.д.).

Пример кода для регламентного задания

Проанализируем, как может выглядеть процедура, выполняемая в регламентном задании.


Процедура СоздатьНарядыПоРасписанию() Экспорт

    ТекущаяДата = ТекущаяДата();

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    ВидыТО.Ссылка,
        |    ВидыТО.РасписаниеXML
        |ИЗ
        |    Справочник.ВидыТО КАК ВидыТО
        |ГДЕ
        |    ВидыТО.РасписаниеXML <> """"";
        
    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();

    Пока Выборка.Следующий() Цикл
        
        // Пропускаем, если реквизит пустой
        Если НЕ ЗначениеЗаполнено(Выборка.РасписаниеXML) Тогда
            Продолжить;
        КонецЕсли;

        // Десериализуем расписание из строки
        ЧтениеXML = Новый ЧтениеXML;
        ЧтениеXML.УстановитьСтроку(Выборка.РасписаниеXML);
        
        Попытка
            Расписание = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
        Исключение
            // Записать в журнал ошибку чтения XML
            Продолжить;
        КонецПопытки;
        
        // Проверяем, нужно ли выполнять задание сегодня
        Если Расписание.ТребуетсяВыполнение(ТекущаяДата) Тогда
        
            // Создаем документ "Наряд"
            НовыйНаряд = Документы.Наряд.СоздатьДокумент();
            НовыйНаряд.Дата = ТекущаяДата;
            НовыйНаряд.ВидТО = Выборка.Ссылка;
            // ... заполняем остальные реквизиты ...
            
            Попытка
                НовыйНаряд.Записать();
            Исключение
                // Записать в журнал ошибку создания документа
            КонецПопытки;
            
        КонецЕсли;
        
    КонецЦикла;

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

Преимущества такого подхода

Этот метод является стандартной практикой для решения подобных задач и имеет ряд весомых плюсов:

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

← На главную