При программной интеграции баз данных через COMConnector нередко возникает ситуация, когда создание и простая запись объекта (РежимЗаписиДокумента.Запись) в базе-приемнике выполняются успешно, а попытка проведения (РежимЗаписиДокумента.Проведение) вызывает ошибку либо завершается отказом. Разберем основные причины такого поведения и пошагово выясним, как правильно диагностировать и устранить проблему.
Если метод проведения падает с системным сбоем или вызывающая база не возвращает внятного описания, первым делом обернем вызов в конструкцию Попытка ... Исключение. Это позволит получить детальный текст ошибки из контекста подключенной базы.
Посмотрим на пример правильного перехвата исключения:
Попытка
// Используем перечисления именно из COM-объекта подключенной базы
ОбъектCOM.Записать(V8.РежимЗаписиДокумента.Проведение, V8.РежимПроведенияДокумента.Неоперативный);
Исключение
ТекстОшибки = ОписаниеОшибки();
ЗаписьЖурналаРегистрации("COM-интеграция", УровеньЖурналаРегистрации.Ошибка,,, ТекстОшибки);
ВызватьИсключение "Ошибка проведения документа через COM: " + ТекстОшибки;
КонецПопытки;
По умолчанию второй параметр метода Записать() имеет значение РежимПроведенияДокумента.Оперативный. Если дата создаваемого документа отличается от текущего системного времени сервера (документ оформляется задним числом или будущей датой), платформа может заблокировать оперативное проведение или выдать ошибку контроля времени.
Проанализируем эту ситуацию: чтобы исключить конфликт оперативных отметок времени, всегда передавайте параметр неоперативного проведения явно, используя перечисление внешней базы:
РежимПроведения = V8.РежимПроведенияДокумента.Неоперативный;
РежимЗаписи = V8.РежимЗаписиДокумента.Проведение;
ОбъектCOM.Записать(РежимЗаписи, РежимПроведения);
В момент проведения документа платформа инициирует выполнение процедур ОбработкаПроведения, вызовы подписок на события, процедур формирования движений по регистрам и проверок остатков. Если в цепочке вызовов задействован общий модуль, у которого в свойствах не установлен флаг Внешнее соединение, платформа сгенерирует исключение, так как функционал модуля окажется недоступен в COM-сеансе.
Разберем по шагам, что необходимо проверить в конфигураторе базы-приемника:
#Если Клиент, вызовы диалоговых окон, предупреждений, методов работы с формами или оповещениями недопустимы при работе через COM и приводят к аварийной остановке выполнения.При интерактивном входе пользователя запускаются модули клиентского приложения, в которых обычно устанавливаются параметры сеанса (например, ТекущийПользователь, подразделение, склад по умолчанию). В сеансе COM-соединения отрабатывает исключительно МодульСеанса (событие УстановкаПараметровСеанса).
Если бизнес-логика проведения обращается к неинициализированным параметрам сеанса или переменным, проведение завершится ошибкой либо взведет признак Отказ = Истина. Также убедимся, что у учетной записи, под которой выполняется COM-подключение, достаточно прав на запись и проведение документов данного типа, а также на запись во все регистры, по которым формируются движения.
Вместо прямой передачи команд объекту через COM надежнее создать в базе-приемнике специальный экспортный метод в общем модуле с включенными признаками Сервер и Внешнее соединение. Это позволит выполнить всю логику проведения в нативном серверном контексте базы-приемника.
Рассмотрим пример реализации такого метода в базе-приемнике:
// В общем модуле базы-приемника
Функция ПровестиДокументПоСсылке(СсылкаНаДокумент) Экспорт
Результат = Новый Структура("Успех, ТекстОшибки", Истина, "");
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Если ДокументОбъект = Неопределено Тогда
Результат.Успех = Ложь;
Результат.ТекстОшибки = "Документ не найден по переданной ссылке.";
Возврат Результат;
КонецЕсли;
Попытка
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
Исключение
Результат.Успех = Ложь;
Результат.ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Возврат Результат;
КонецФункции
Тогда в исходной базе вызов сведется к простой и надежной конструкции:
Результат = V8.ИнтеграцияСервер.ПровестиДокументПоСсылке(СсылкаCOM);
Если Не Результат.Успех Тогда
ВызватьИсключение "Ошибка проведения: " + Результат.ТекстОшибки;
КонецЕсли;
Если COM-соединение продолжает вызывать сложности из-за разрядности библиотек или нестабильности сетевого окружения, рассмотрим альтернативные варианты взаимодействия баз:
/odata/standard.odata/Document_.../Post()).ОбменДанными.Загрузка = Истина) и последующее проведение в фоновом режиме регламентным заданием целевой базы.