Как выполнить обработку из другой базы 1С через COM-соединение и получить результат

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

При интеграции двух информационных баз 1С часто возникает задача: выполнить алгоритм или получить данные из внешней базы (База 1), находясь в контексте текущей базы (База 2). Начинающие разработчики нередко пытаются напрямую открыть форму внешней обработки через COM-соединение, однако такой подход принципиально невозможен из-за архитектурных ограничений компоненты V83.COMConnector.

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

Архитектурные ограничения COM-соединения

Проанализируем ключевое различие между технологиями подключения к базам 1С:

  1. V83.COMConnector: инициализирует серверную сессию без создания графической оболочки пользователя. В этом контексте полностью отсутствуют объекты интерфейса — такие как Форма, коллекция ЭлементыФормы (или Элементы в управляемом приложении), диалоговые окна и предупреждения. Если код процедуры обращается к экранным элементам, обращение через COMConnector завершится аварийно с ошибкой «Метод объекта не обнаружен» или исключением времени выполнения.
  2. V83.Application: запускает полноценный клиентский процесс с возможностью отображения окон (при установке свойства Visible = Истина). Однако этот вариант требует отдельной клиентской лицензии, доступен только под управлением операционной системы Windows и не может использоваться в серверном коде или фоновых заданиях.

Правильный архитектурный подход: интерфейсная форма со всеми элементами управления (кнопками, полями ввода) создается в базе-клиенте (База 2), а из базы-источника (База 1) через COMConnector вызываются только серверные алгоритмы и передаются «чистые» данные (числа, строки, даты, таблицы значений или табличные документы).

Шаг 1. Перенос логики в модуль объекта обработки

Выясним причину ошибки при попытке вызвать метод формы через COM. Модуль формы внешней базы недоступен без создания самого интерфейса. Поэтому все алгоритмы обработки данных необходимо перенести из модуля формы в модуль объекта обработки и объявить их с ключевым словом Экспорт.

Посмотрим на пример экспортной функции в модуле объекта обработки рс во внешней базе (База 1):


Функция ПолучитьИнфуИзМодуляОбработки(НомерКарты) Экспорт
    
    // Формируем табличный документ по алгоритму обработки
    ТабДок = Новый ТабличныйДокумент;
    
    // Выполняем требуемый расчет или выборку данных
    ВывестиНаЭкран(НомерКарты, ТабДок);
    
    // Сохраняем результат во временный файл для передачи
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("mxl");
    ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.MXL);
    
    Возврат ИмяВременногоФайла;
    
КонецФункции

Шаг 2. Подключение и запуск метода обработки из внешней базы

Теперь разберем, как в вызывающей базе (База 2) инициализировать COM-соединение, создать экземпляр обработки, передать в нее параметры и прочитать сформированный результат:


Функция ПолучитьТабличныйДокументИзБазы1(НомерКарты)
    
    ТабДок = Новый ТабличныйДокумент;
    
    // 1. Инициализация COM-коннектора
    ComConnector = Новый COMОбъект("V83.COMConnector");
    СтрокаПодключения = "Srvr=""srv-1c""; Ref=""zup_db""; Usr=""Admin""; Pwd=""SecretPass"";";
    
    Попытка
        ComConnection = ComConnector.Connect(СтрокаПодключения);
    Исключение
        ВызватьИсключение "Ошибка подключения к внешней базе: " + ОписаниеОшибки();
    КонецПопытки;
    
    // 2. Создание объекта обработки во внешней базе
    ОбъектОбработки = ComConnection.Обработки.рс.Создать();
    
    // 3. Вызов экспортного метода
    ПутьКФайлу = ОбъектОбработки.ПолучитьИнфуИзМодуляОбработки(НомерКарты);
    
    // 4. Чтение полученного макета в текущей базе
    Если ЗначениеЗаполнено(ПутьКФайлу) Тогда
        ТабДок.Прочитать(ПутьКФайлу);
    КонецЕсли;
    
    Возврат ТабДок;
    
КонецФункции

Шаг 3. Выполнение прямого запроса через COM-соединение

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


Процедура ЗапроситьДанныеСотрудникаПоКарте(ComConnection, НомерКарты)
    
    // Создаем объект Запрос в контексте COM-соединения
    КомЗапрос = ComConnection.NewObject("Запрос");
    КомЗапрос.Текст = 
        "ВЫБРАТЬ
        |    Сфинкс.ФИО КАК ФИО,
        |    Сфинкс.ФИО.Наименование КАК ФИОНаименование
        |ИЗ
        |    РегистрСведений.Сфинкс КАК Сфинкс
        |ГДЕ
        |    Сфинкс.Карта = &Карта";
        
    КомЗапрос.УстановитьПараметр("Карта", Формат(НомерКарты, "ЧГ=0"));
    
    Результат = КомЗапрос.Выполнить().Выбрать();
    
    Пока Результат.Следующий() Цикл
        // Обратите внимание: обращение к полям-ссылкам лучше делать через простые типы (Наименование, Код)
        Сообщить("Найден сотрудник: " + Результат.ФИОНаименование);
    КонецЦикла;
    
КонецПроцедуры

Шаг 4. Сериализация и передача сложных структур данных

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

Посмотрим на пример быстрой выгрузки и загрузки таблицы через внутреннюю строковую сериализацию 1С:


// Выполняем запрос во внешней базе
ЗапросCOM = ComConnection.NewObject("Запрос");
ЗапросCOM.Текст = "ВЫБРАТЬ Номенклатура.Наименование КАК Товар, КоличествоОстаток КАК Остаток ИЗ РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК Остатки";

// Выгружаем результат в ТЗ внешней базы
ТЗВнешняя = ЗапросCOM.Выполнить().Выгрузить();

// Сериализуем таблицу в строку во внешней базе и десериализуем в локальной
СтрокаДанных = ComConnection.ЗначениеВСтрокуВнутр(ТЗВнешняя);
ТЗЛокальная = ЗначениеИзСтрокиВнутр(СтрокаДанных);

// Теперь ТЗЛокальная — это полноценная локальная ТаблицаЗначений текущей базы

Особенности при работе с управляемыми формами

Если форма в базе-клиенте реализована на управляемых формах, учитывайте следующие правила:

  1. Разделение контекста: подключение к COM-объекту и выполнение запросов должны производиться строго на сервере (процедуры с директивой &НаСервере или &НаСервереБезКонтекста).
  2. Обращение к элементам: вместо устаревшей коллекции ЭлементыФормы используется коллекция Элементы. Значения полей ввода привязываются к реквизитам формы, а не присваиваются свойству .Значение визуального элемента.
  3. Отображение результата: полученный ТабличныйДокумент помещается в реквизит формы типа ТабличныйДокумент, связанный с элементом формы «Поле табличного документа».
← На главную