Как программно отменить проведение другого документа из модуля проведения в 1С 7.7?

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

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

Понимание природы ограничения

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

Решение через использование библиотеки Formex

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

Для реализации этого решения выполните следующие действия:

  1. В модуле формы журнала документов (или ином контексте, где доступен ТекущийДокумент) добавьте обработчик внешнего события:

Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    Если Событие = "СделатьНепроведенным" Тогда
        Док = СоздатьОбъект("Документ");
        Док.НайтиДокумент(ТекущийДокумент);
        Док.СделатьНеПроведенным();
        Форма.Обновить();
    КонецЕсли;
КонецПроцедуры
  1. В модуле проведения документа, из которого необходимо инициировать отмену, добавьте вызов метода через объект Сервис:

Сервис = СоздатьОбъект("Сервис");
Сервис.ВнешнееСобытие(Вид(), "СделатьНепроведенным", "Форма");
Возврат;

Этот подход позволяет асинхронно передать команду системе. Транзакция основного документа завершается штатно, а затем срабатывает обработчик ОбработкаВнешнегоСобытия, который беспрепятственно выполняет отмену проведения целевого документа.

Решение через глобальную процедуру ОбработкаОжидания

Если по каким-либо причинам использование сторонних компонент невозможно, существует альтернативный способ через ОбработкаОжидания(). Рассмотрим основные принципы этого метода:

  1. Создайте глобальную переменную или СписокЗначений, в который помещайте ссылку на документ, требующий отмены проведения.
  2. В глобальном модуле настройте ОбработкаОжидания("ИмяВашейПроцедуры", интервал).
  3. Внутри самой процедуры-обработчика проверяйте наличие данных в глобальной переменной. Если документ там присутствует — выполняйте метод СделатьНеПроведенным() и очищайте переменную.

Важное замечание: Метод с ОбработкаОжидания менее предпочтителен, так как он создает временную задержку и требует строгой обработки конкурентного доступа, если несколько пользователей одновременно инициируют подобные действия.

Рекомендации по проектированию

Проанализируем ситуацию: чтобы избежать подобных сложностей в будущем, старайтесь следовать правилам архитектуры 1С 7.7:

Таким образом, мы разобрали, почему стандартные методы не работают внутри транзакции проведения, и выяснили, что ключ к успеху — это вынос операции за пределы текущего стека выполнения.

← На главную