Как создать документ в другой базе 1С через COM-соединение и избежать ошибок контекста

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

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

Подключение к базе-приемнику и создание нового документа

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


// Получаем имя COM-соединителя для текущей платформы
ИмяCOM = ОбщегоНазначенияКлиентСервер.ИмяCOMСоединителя(); // Например, "V83.COMConnector"
COMConnector = Новый COMObject(ИмяCOM); 

Попытка
    // Устанавливаем соединение с файловой базой (для серверной используем Srvr="..." ; Ref="...")
    СоединениеБД = COMConnector.Connect("File=""" + СокрЛП(КаталогБазы) + """; Usr=""Пользователь""; Pwd=""Пароль"";");
Исключение
    Сообщить("Не удалось установить соединение с базой: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// Создаем новый документ "Платежное поручение входящее" в приемнике
ППВ = СоединениеБД.Документы.ПлатежноеПоручениеВходящее.СоздатьДокумент();
ППВ.Дата = ТекущаяДата();
ППВ.ЗаполнитьНачальныеРеквизиты(); // Если метод объявлен как экспортный

// Записываем документ
ППВ.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ успешно записан в приемнике!");

Обратите внимание на обращение к методам менеджера: вызов выполняется строго через полученный объект COM-соединения, например СоединениеБД.Документы.РеализацияТоваровУслуг.СоздатьДокумент().

Почему возникает ошибка при вызове «СоздатьДокумент» или открытии модуля?

В процессе выполнения кода разработчики часто сталкиваются со следующей ошибкой:

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

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

Выясним, как разрешить эту проблему в зависимости от возможности менять конфигурацию-приемник:

  1. Если конфигурацию-приемник можно дорабатывать: необходимо обернуть интерактивные вызовы в инструкцию препроцессора #Если Клиент Тогда ... #КонецЕсли или #Если ТолстыйКлиентОбычноеПриложение Тогда ... #КонецЕсли.
  2. Использование расширений конфигурации: если основная конфигурация находится на поддержке, можно создать расширение и с помощью аннотаций (например, &Вместо) переопределить методы, содержащие вызов интерфейсных функций.
  3. Переход на Automation-сервер (V83.Application): вместо COMConnector можно использовать `V83.Application`. Этот режим запускает полноценный клиент 1С (его можно сделать невидимым, установив Visible = Ложь), в котором доступен весь интерфейсный контекст.

Ошибка «Метод объекта не обнаружен» при вызове «Записать»

Другая распространенная проблема возникает непосредственно при записи документа через COM-соединение:

Ошибка при вызове метода контекста (Записать)... Метод объекта не обнаружен (ИмяПроцедуры)

Разберем основные причины этого поведения:

  1. Свойства общих модулей: При работе через V83.COMConnector платформой компилируются только те общие модули, у которых в свойствах установлен флаг «Внешнее соединение». Если обработчик события объекта (например, ПередЗаписью) обращается к функции модуля, у которого этот флаг снят, вызов завершится ошибкой.
  2. Поведение флага ОбменДанными.Загрузка: Установка свойства ППВ.ОбменДанными.Загрузка = Истина; отключает платформенные проверки, но не отменяет сам вызов программного кода в обработчиках событий объекта. Код в модуле будет пропущен только в том случае, если разработчик конфигурации явным образом прописал условие в самом начале процедуры:
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    Если такого условия в модуле объекта нет, весь код проверки прав, подсистем или периода будет выполняться в полном объеме.

Альтернативные способы передачи данных без изменения конфигурации

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

  1. Загрузка данных на стороне приемника: Перенести логику создания документов на сторону базы-приемника. В ней создается внешняя обработка, которая через COM подключается к источнику, вычитывает реквизиты и создает документ локально в своем полноценном контексте.
  2. Универсальный обмен данными XML: Использование стандартной подсистемы выгрузки и загрузки данных через файлы XML или прямое подключение. Стандартные механизмы обмена умеют корректно отключать бизнес-проверки при переносе.
  3. HTTP-сервисы и REST API (OData): Запись данных через стандартный интерфейс OData или кастомные HTTP-сервисы с передачей данных в формате JSON.
← На главную