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

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

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

В этой статье мы подробно разберем, как правильно организовать архитектуру вызова, вынести логику сбора данных в доступный модуль и сериализовать результат для передачи по COM-каналу.

Ограничения COM-соединения в 1С

Проанализируем ключевые особенности работы платформы 1С через COM-соединение:

  1. Отсутствие интерактивного контекста. В COM-сессии не существует графического интерфейса. Любое обращение к форме отчета, элементам формы (ЭлементыФормы), а также вызовы диалоговых окон (Предупреждение, Вопрос) вызовут критическую ошибку выполнения. Процедуры, находящиеся в модуле формы, вызывать снаружи нельзя.
  2. Невозможность прямой передачи сложных объектов. Через COM-соединение между разными процессами 1С передаются только примитивные типы (числа, строки, булево, даты) и некоторые базовые структуры. Передать объект ТаблицаЗначений «как есть» не получится — вызывающая база не сможет его прочитать напрямую.

Шаг 1. Подготовка кода в подключаемой базе (База Б)

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

Вариант А. Размещение функции в модуле объекта или менеджера отчета

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

Посмотрим на пример экспортной функции в модуле объекта отчета:


Функция СформироватьТаблицуДанныхXML() Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Продажи.Номенклатура КАК Номенклатура,
        |	Продажи.Количество КАК Количество,
        |	Продажи.Сумма КАК Сумма
        |ИЗ
        |	РегистрНакопления.Продажи КАК Продажи";
    
    ТЗДанные = Запрос.Выполнить().Выгрузить();
    
    // Преобразуем таблицу значений в внутреннюю XML-строку 1С
    Возврат ЗначениеВСтрокуВнутр(ТЗДанные);

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

Вариант Б. Использование общего модуля

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

Шаг 2. Сериализация и передача таблицы значений

Для передачи таблицы значений из базы Б в базу А преобразуем её в строковый вид. Рассмотрим два наиболее надежных способа сериализации:

  1. Использование ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр():

    Этот способ является самым простым и точным при обмене между одинаковыми или близкими конфигурациями 1С. Он полностью сохраняет внутренние типы данных и структуру таблицы.

  2. Использование СериализаторXDTO или XMLЗначение():

    Таблица значений выгружается в XML-строку на стороне подключаемой базы и затем считывается в вызывающей базе. Этот способ отлично подходит для универсальной передачи данных.

Шаг 3. Подключение и получение данных в вызывающей базе (База А)

Теперь разберем, как написать код в исходной базе (База А) для выполнения подключения, запуска функции сбора данных и восстановления полученной таблицы значений.

Проанализируем пример кода с использованием COM-соединения COMConnector:


// 1. Инициализируем COM-соединение к файловой базе
COMОбъект = Новый COMОбъект("V83.COMConnector");

ПутьКБазе = "File=""C:\Bases\TradeBase"";Usr=""Администратор"";Pwd=""123"";";
Попытка
    Подключение = COMОбъект.Connect(ПутьКБазе);
Исключение
    Сообщить("Ошибка подключения к базе: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// 2. Создаем объект отчета в подключаемой базе и вызываем экспортную функцию
ОтчетОбъект = Подключение.Отчеты.ИмяОтчета.Создать();
СтрокаДанныхXML = ОтчетОбъект.СформироватьТаблицуДанныхXML();

// 3. Восстанавливаем таблицу значений из полученной строки
ТЗИзБазыБ = ЗначениеИзСтрокиВнутр(СтрокаДанныхXML);

// 4. Используем полученную таблицу значений в текущем отчете
Для Каждого СтрИзБ Из ТЗИзБазыБ Цикл
    // Обработка полученных строк и дополнение итогового отчета
КонецЦикла;

Если экспортная функция размещена в модуле менеджера отчета, обращение к ней выполняется еще проще — без создания экземпляра объекта:


СтрокаДанныхXML = Подключение.Отчеты.ИмяОтчета.СформироватьДанныеВМодулеМенеджера();
ТЗИзБазыБ = ЗначениеИзСтрокиВнутр(СтрокаДанныхXML);

Важные рекомендации при работе с файловыми базами

  1. Разрядность компонентов: Если вызывающий сеанс 1С работает в 64-разрядном режиме, а подключаемая библиотека comcntr.dll зарегистрирована как 32-разрядная, прямое подключение вернет ошибку. В этом случае требуется настройка компонента в «Службах компонентов» Windows (COM+).
  2. Блокировки файлов: При вызове COM-соединения к файловой базе .1CD создается полноценный сеанс. Убедитесь, что сеанс корректно завершается, чтобы не удерживать файловые блокировки базы-источника.
  3. Преобразование ссылочных типов: При передачи ссылок на справочники или документы между разными базами помните, что ссылки одного типа из базы Б не будут валидны в базе А. Передавайте в строковом виде наименования, коды или УИД (УникальныйИдентификатор), чтобы затем найти соответствующие объекты в целевой базе.
← На главную