Почему документ 1С не проводится через COM-соединение и как это исправить?

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

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

1. Диагностика ошибки: перехват исключения

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

Посмотрим на пример правильного перехвата исключения:


Попытка
    // Используем перечисления именно из COM-объекта подключенной базы
    ОбъектCOM.Записать(V8.РежимЗаписиДокумента.Проведение, V8.РежимПроведенияДокумента.Неоперативный);
Исключение
    ТекстОшибки = ОписаниеОшибки();
    ЗаписьЖурналаРегистрации("COM-интеграция", УровеньЖурналаРегистрации.Ошибка,,, ТекстОшибки);
    ВызватьИсключение "Ошибка проведения документа через COM: " + ТекстОшибки;
КонецПопытки;

2. Явное указание неоперативного режима проведения

По умолчанию второй параметр метода Записать() имеет значение РежимПроведенияДокумента.Оперативный. Если дата создаваемого документа отличается от текущего системного времени сервера (документ оформляется задним числом или будущей датой), платформа может заблокировать оперативное проведение или выдать ошибку контроля времени.

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


РежимПроведения = V8.РежимПроведенияДокумента.Неоперативный;
РежимЗаписи = V8.РежимЗаписиДокумента.Проведение;

ОбъектCOM.Записать(РежимЗаписи, РежимПроведения);

3. Проверка свойств общих модулей и директив компиляции

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

Разберем по шагам, что необходимо проверить в конфигураторе базы-приемника:

  1. Откроем свойства общих модулей, которые участвуют в проведении документа и формировании движений по регистрам (включая обработчики подписок на события).
  2. Убедимся, что рядом с признаком Сервер установлен флаг Внешнее соединение.
  3. Проверим код на наличие директив клиентского контекста. Конструкции вида #Если Клиент, вызовы диалоговых окон, предупреждений, методов работы с формами или оповещениями недопустимы при работе через COM и приводят к аварийной остановке выполнения.

4. Инициализация параметров сеанса и контроль прав

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

Если бизнес-логика проведения обращается к неинициализированным параметрам сеанса или переменным, проведение завершится ошибкой либо взведет признак Отказ = Истина. Также убедимся, что у учетной записи, под которой выполняется COM-подключение, достаточно прав на запись и проведение документов данного типа, а также на запись во все регистры, по которым формируются движения.

5. Вынос проведения в экспортную процедуру базы-приемника

Вместо прямой передачи команд объекту через COM надежнее создать в базе-приемнике специальный экспортный метод в общем модуле с включенными признаками Сервер и Внешнее соединение. Это позволит выполнить всю логику проведения в нативном серверном контексте базы-приемника.

Рассмотрим пример реализации такого метода в базе-приемнике:


// В общем модуле базы-приемника
Функция ПровестиДокументПоСсылке(СсылкаНаДокумент) Экспорт

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

    Попытка
        ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
    Исключение
        Результат.Успех = Ложь;
        Результат.ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;

    Возврат Результат;

КонецФункции

Тогда в исходной базе вызов сведется к простой и надежной конструкции:


Результат = V8.ИнтеграцияСервер.ПровестиДокументПоСсылке(СсылкаCOM);
Если Не Результат.Успех Тогда
    ВызватьИсключение "Ошибка проведения: " + Результат.ТекстОшибки;
КонецЕсли;

Альтернативные архитектурные решения

Если COM-соединение продолжает вызывать сложности из-за разрядности библиотек или нестабильности сетевого окружения, рассмотрим альтернативные варианты взаимодействия баз:

  1. HTTP-сервисы: разработка собственного REST/HTTP-сервиса в базе-приемнике. Это платформонезависимый подход, не требующий регистрации COM-компонентов в операционной системе.
  2. Стандартный интерфейс OData: использование встроенного REST API платформы 1С для записи и проведения объектов через стандартные HTTP-запросы (метод /odata/standard.odata/Document_.../Post()).
  3. Отложенное проведение: быстрая запись документа через COM с отключенными проверками (ОбменДанными.Загрузка = Истина) и последующее проведение в фоновом режиме регламентным заданием целевой базы.
← На главную