Как реализовать отложенные операции и очередь задач в 1С 7.7?

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

В платформе 1С:Предприятие 7.7 отсутствует штатный механизм фоновых и регламентных заданий, привычный разработчикам на платформах v8. Однако при построении сложных бизнес-процессов часто возникает необходимость вынести трудоемкие алгоритмы за пределы транзакции проведения документа. Например, при изменении приходной накладной требуется автоматически переоформить или перепровести связанные документы уценки, установки цен или выписки счетов-фактур, не заставляя пользователя ждать окончания всех связанных вычислений.

Рассмотрим подробнее основные архитектурные подходы к организации очереди задач и отложенной обработки данных в «клюшках».

Вариант 1. Использование реестра задач и выделенного сеанса-робота

Наиболее надежный и масштабируемый способ заключается в разделении процесса регистрации задачи и её непосредственного выполнения. Данный вариант подходит как для файловых баз (DBF), так и для версий на базе MS SQL Server.

Разберем по шагам схему реализации:

  1. Создание реестра отложенных действий. В конфигураторе создается служебный справочник (или служебный регистр сведений/накопления). В нем фиксируются ссылка на документ-источник, тип операции, текущий статус (например, «Новая», «В обработке», «Ошибка», «Выполнена»), количество попыток и текст ошибки.
  2. Регистрация события. При изменении или проведении документа в процедуре ОбработкаПроведения() формируется новая запись в реестре. Поведение документа становится атомарным: документ проводится быстро, а запись в реестре сигнатурно указывает на необходимость последующей обработки.
  3. Обработка задач внешним роботом. Через планировщик операционной системы (Windows Task Scheduler) или с помощью запущенного служебного сеанса 1С в монопольном/отдельном режиме периодически отрабатывает обработка, которая выбирает задачи со статусом «Новая» и выполняет нужные действия.

При организации фонового процесса с использованием метода ОбработкаОжидания() важно учитывать технические особенности платформы 1С 7.7:

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

Вариант 2. Вызов асинхронных событий через ВК FormEx

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

Метод глСервис.ВнешнееСобытие() генерирует внешнее событие. Полноценная обработка этого события происходит только тогда, когда текущая процедура проведения полностью завершена и транзакция зафиксирована.

Посмотрим на пример кода в модуле документа при вызове асинхронного генератора счетов-фактур или пересчета цен:


Процедура ОбработкаПроведения()
    
    // Выполнение штатных движений по регистрам
    Если (ПустоеЗначение(ВидыДвижений) = 1) ИЛИ (Найти(ВидыДвижений, "Регистр") <> 0) Тогда
        ПроведениеПоРегистрам();
        Если СтатусВозврата() = 0 Тогда Возврат; КонецЕсли;
    КонецЕсли;
    
    // Проверка условий, при которых требуется асинхронная вызовет
    Если (ГрупповаяОбработка() + глГрупповаяОбработка) <> 0 Тогда 
        Возврат; 
    КонецЕсли;
    
    Если ПустоеЗначение(глСервис) = 1 Тогда 
        Возврат; // Компонента FormEx не загружена
    КонецЕсли;
    
    // Передаем событие для обработки в Глобальный модуль после закрытия транзакции
    глСервис.ВнешнееСобытие("FAKIR", "ГЕНЕРАЦИЯСЧФВЫДАННЫЙАВАНС", ЗначениеВСтрокуВнутр(ТекущийДокумент()));

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

Далее в процедуре ОбработкаВнешнегоСобытия() глобального модуля или формы происходит перехват данного события и запуск необходимого алгоритма:


Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    Если (Источник = "FAKIR") И (Событие = "ГЕНЕРАЦИЯСЧФВЫДАННЫЙАВАНС") Тогда
        ДокИсточник = ЗначениеИзСтрокиВнутр(Данные);
        // Выполняем создание или перепроведение подчиненных документов
        ОбработатьСвязанныеДокументы(ДокИсточник);
    КонецЕсли;
КонецПроцедуры

Сравнение подходов

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

  1. Реестр задач + Сеанс-робот: Оптимален для критически важных процессов, макро-пересчетов и высоконагруженных баз с большим числом пользователей. Обеспечивает высокую надежность, не блокирует работу пользователей и фиксирует историю ошибок.
  2. Внешнее событие (FormEx): Идеально подходит для быстрой интерактивной работы, когда подчиненный документ должен появиться сразу после нажатия кнопки «Провести», но без риска вызвать рекурсивное блокирование транзакций внутри ОбработкаПроведения().
← На главную