При межбазовом обмене или построении консолидированной отчетности часто возникает задача: подключиться из одной базы 1С к другой (в том числе файловой), сформировать данные на стороне подключаемой базы и вернуть результат обратно. Однако при попытке сделать это «в лоб» разработчики сталкиваются с двумя главными препятствиями: отсутствием пользовательского интерфейса в COM-сессии и невозможностью прямо передавать сложные типы данных, такие как ТаблицаЗначений.
В этой статье мы подробно разберем, как правильно организовать архитектуру вызова, вынести логику сбора данных в доступный модуль и сериализовать результат для передачи по COM-каналу.
Проанализируем ключевые особенности работы платформы 1С через COM-соединение:
ЭлементыФормы), а также вызовы диалоговых окон (Предупреждение, Вопрос) вызовут критическую ошибку выполнения. Процедуры, находящиеся в модуле формы, вызывать снаружи нельзя.ТаблицаЗначений «как есть» не получится — вызывающая база не сможет его прочитать напрямую.Поскольку вызывать процедуры из формы отчета через COM невозможно, нам необходимо вынести алгоритм сбора и формирования данных из модуля формы. Рассмотрим два основных варианта решения этой задачи.
Вариант А. Размещение функции в модуле объекта или менеджера отчета
Выберем модуль объекта или модуль менеджера отчета в подключаемой базе и создадим в нем экспортную функцию. Эта функция должна выполнять запрос, собирать данные и возвращать их в виде таблицы значений или сразу сериализованной строки.
Посмотрим на пример экспортной функции в модуле объекта отчета:
Функция СформироватьТаблицуДанныхXML() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура КАК Номенклатура,
| Продажи.Количество КАК Количество,
| Продажи.Сумма КАК Сумма
|ИЗ
| РегистрНакопления.Продажи КАК Продажи";
ТЗДанные = Запрос.Выполнить().Выгрузить();
// Преобразуем таблицу значений в внутреннюю XML-строку 1С
Возврат ЗначениеВСтрокуВнутр(ТЗДанные);
КонецФункции
Вариант Б. Использование общего модуля
Если логика сбора данных не привязана строго к объекту отчета, вынесем её в отдельный общий модуль. Обратите внимание: в свойствах общего модуля обязательно должен быть установлен флаг Внешнее соединение, иначе его процедурам и функциям нельзя будет обратиться через COM.
Для передачи таблицы значений из базы Б в базу А преобразуем её в строковый вид. Рассмотрим два наиболее надежных способа сериализации:
ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр():
Этот способ является самым простым и точным при обмене между одинаковыми или близкими конфигурациями 1С. Он полностью сохраняет внутренние типы данных и структуру таблицы.
СериализаторXDTO или XMLЗначение():
Таблица значений выгружается в XML-строку на стороне подключаемой базы и затем считывается в вызывающей базе. Этот способ отлично подходит для универсальной передачи данных.
Теперь разберем, как написать код в исходной базе (База А) для выполнения подключения, запуска функции сбора данных и восстановления полученной таблицы значений.
Проанализируем пример кода с использованием 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);
comcntr.dll зарегистрирована как 32-разрядная, прямое подключение вернет ошибку. В этом случае требуется настройка компонента в «Службах компонентов» Windows (COM+)..1CD создается полноценный сеанс. Убедитесь, что сеанс корректно завершается, чтобы не удерживать файловые блокировки базы-источника.УникальныйИдентификатор), чтобы затем найти соответствующие объекты в целевой базе.