Как настроить автоматическое перезаполнение файла по шаблону при изменении внутреннего документа в 1С:Документооборот 2.1?

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

В типовом функционале программы 1С:Документооборот 2.1 механизм автозаполнения файлов по шаблону по умолчанию отрабатывает лишь один раз — в момент первичного добавления файла из шаблона в карточку документа. Если в дальнейшем пользователь изменяет реквизиты карточки (например, сумму договора, контрагента или контактные данные), файл автоматически не обновляется. Штатная модель взаимодействия требует ручного нажатия команды заполнения файла по данным документа. Полноценное штатное фоновое обновление файлов при любых правках карточки появилось только в редакции «1С:Документооборот 3.0». Для версии 2.1 такую функциональность необходимо реализовывать программно.

При попытке автоматизировать этот процесс разработчики часто сталкиваются с критической проблемой: система уходит в бесконечную рекурсию, а регламентное задание ОбработкаПроизошедшихБизнесСобытий начинает циклически перезаписывать один и тот же документ. Давайте детально разберем природу этой ошибки и рассмотрим надежные варианты решения задачи.

Почему возникает бесконечный цикл при обновлении файла?

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

  1. Пользователь изменяет реквизит внутреннего документа и нажимает кнопку сохранения.
  2. Детектор бизнес-событий фиксирует событие Изменение внутреннего документа и добавляет запись в регистр сведений ПроизошедшиеБизнесСобытия.
  3. Регламентное задание берет событие в обработку и запускает пользовательский обработчик, выполняющий процедуру перезаполнения файла (например, с использованием функционала общего модуля АвтозаполнениеШаблоновФайловКлиентСервер.ЗаполнитьПоляФайлаДаннымиВладельца).
  4. В процессе обновления файла в базе данных модифицируются справочники файлов и версий файлов.
  5. Изменение привязанного файла расценивается системой как модификация самого предмета или фиксируется связанным детектором, в результате чего платформа повторно регистрирует бизнес-событие Изменение внутреннего документа.
  6. Цикл замыкается: задание считывает новое событие и снова инициирует процедуру перезаполнения, забивая очередь регистра и расходуя системные ресурсы сервера.

Чтобы избавиться от бесконечной цепочки, необходимо применить механизм блокировки повторных вызовов. Рассмотрим проверенные способы реализации автоматического обновления.

Способ 1. Использование флага в ДополнительныхСвойствах объекта

Разберем самый чистый способ предотвращения рекурсии на стороне серверного кода. Объект ДополнительныеСвойства существует исключительно во время текущей сессии записи в оперативной памяти и не сохраняется в базу данных. Мы можем установить специальный маркер перед перезаполнением файла и проверять его в обработчиках событий.

Посмотрим на пример кода, который внедряется в модуль объекта документа или в подписку на событие ПередЗаписью / ПриЗаписи:


Если Не Источник.ДополнительныеСвойства.Свойство("ПерезаполнениеФайлаВыполнено") Тогда
    Источник.ДополнительныеСвойства.Вставить("ПерезаполнениеФайлаВыполнено", Истина);
    
    // Выполняем проверку условий и вызов процедуры перезаполнения
    Если АвтозаполнениеТребуется(Источник) Тогда
        ВыполнитьПерезаполнениеФайловПоШаблону(Источник);
    КонецЕсли;
КонецЕсли;

Когда типовые процедуры сохранения файла попытаются снова перезаписать данные документа или отправить его в обработку бизнес-событий, наличие свойства ПерезаполнениеФайлаВыполнено со значением Истина прервет каскадный запуск процедуры.

Способ 2. Проверка модифицированности значимых реквизитов

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

Разберем по шагам, как построить подобную проверку в событии ПриЗаписи или ПередЗаписью:

  1. Получаем ссылку на текущий объект. Если ссылка новая (объект создается впервые), перезаполнение не требуется, так как отработает типовой механизм создания из шаблона.
  2. Считываем из базы данных текущие значения только тех реквизитов, которые реально выводятся в поля шаблона (например, Сумма, Контрагент, СрокИсполнения).
  3. Сравниваем считанные значения с реквизитами записываемого объекта Источник.
  4. Если ни один из значимых реквизитов не изменился, прерываем выполнение алгоритма.

Посмотрим на пример функции проверки модифицированности:


Функция АвтозаполнениеТребуется(Источник)
    
    Если Источник.ЭтоНовый() Тогда
        Возврат Ложь;
    КонецЕсли;
    
    РеквизитыБазы = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
        Источник.Ссылка, 
        "Сумма, Стороны, ДатаРегистрации"
    );
    
    Если Источник.Сумма <> РеквизитыБазы.Сумма
        Или Источник.ДатаРегистрации <> РеквизитыБазы.ДатаРегистрации Тогда
        Возврат Истина;
    КонецЕсли;
    
    Возврат Ложь;
    
КонецФункции

Способ 3. Перенос перезаполнения в форму документа

Если бизнес-требования не настаивают на выполнении фонового автозаполнения в фоновых заданиях без участия пользователя, наиболее надежный и безопасный путь — внедрение в форму документа через расширение конфигурации. В этом сценарии обновление происходит непосредственно в контексте сохранения формы пользователем, минуя механизм бизнес-событий.

Рассмотрим порядок действий:

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

Ограничения и технические риски, которые важно учесть

При внедрении программного перезаполнения шаблонов обязательно обратим внимание на следующие архитектурные особенности системы:

  1. Захват файлов на редактирование: Перед программной перезаписью файла в коде обязательно проверяем признак Редактирует. Если файл открыт кем-то из пользователей на редактирование (значение реквизита не равно пустой ссылке справочника Пользователи), перезаполнять его нельзя. Попытка перезаписи приведет либо к исключительной ситуации блокировки, либо к потере изменений, внесенных сотрудником вручную.
  2. Наличие электронной подписи: Если документ или присоединенный файл подписан одной или несколькими ЭП, модификация бинарного содержимого строго запрещена. Любое программное вмешательство в файл делает существующую электронную подпись недействительной. При обнаружении подписей алгоритм должен прерывать обработку и выводить соответствующее предупреждение.
  3. Лавинообразный рост версий файлов: При активной работе и включенном версионировании справочника ВерсииФайлов каждая процедура перезаполнения генерирует новую запись бинарных данных. Регулярные правки документов способны за короткий срок переполнить дисковое пространство томов хранения. Рекомендуется настроить регламентное задание очистки устаревших версий файлов.
  4. Специфика серверной платформы: Если шаблоны хранятся в устаревших форматах doc или dot, их обработка может требовать наличия установленного пакета Microsoft Office и вызова COM-соединений. На серверах под управлением 64-битной версии «1С:Предприятия» или ОС Linux это вызывает падение процессов. Для стабильной работы автозаполнения на сервере необходимо перевести все используемые шаблоны в современные форматы docx или dotx, обработка которых выполняется платформой встроенными средствами без использования COM-объектов.
← На главную