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

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

При разработке внешних отчетов часто возникает задача объединения данных из разных информационных баз. Например, нам необходимо дополнить отчет в «1С:Управление торговлей 10.3» данными о путевых листах из конфигурации «Управление автотранспортом» (УАТ). Основная сложность заключается в том, что метаданные внешней базы (таблицы документов, справочников) недоступны напрямую в конфигураторе текущей базы, а объекты, полученные через COM-соединение, нельзя напрямую использовать в системе компоновки данных (СКД).

В этой статье мы подробно разберем, как правильно установить соединение, выполнить запрос к внешней базе, избежать типичных ошибок при работе с таблицами значений и интегрировать результат в СКД.

Шаг 1. Выбор способа подключения: COMConnector против Application

Разберем, какой объект использовать для связи. В исходном коде часто встречается v82.Application. Этот метод запускает полноценный экземпляр 1С (хотя и в невидимом режиме), что требует значительных ресурсов сервера. Если нам нужно просто прочитать данные, лучше использовать v82.COMConnector.

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


ПараметрыСвязи = "Srvr=""192.168.25.29:1642"";Ref=""uat"";Usr=""User1"";Pwd=""12345"";";
COMСоединитель = Новый COMОбъект("v82.COMConnector");

Попытка
    Подключение = COMСоединитель.Connect(ПараметрыСвязи);
Исключение
    Сообщить("Ошибка подключения: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

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

Проанализируем типичную проблему: почему Конструктор запроса в текущей базе не видит таблицы внешней базы? Ответ прост: Конструктор работает только с локальным деревом метаданных. Чтобы составить запрос к таблице Документ.уатПутевойЛист, которой нет в вашей базе, выполните следующие действия:

  1. Откройте базу-источник (в нашем примере — УАТ) в режиме «Конфигуратор» или «Предприятие».
  2. Используйте консоль запросов, чтобы составить и отладить текст запроса.
  3. Скопируйте полученный текст и вставьте его в код вашей обработки в базе-приемнике.

Посмотрим на пример создания объекта запроса через COM-соединение:


ЗапросВнешний = Подключение.NewObject("Запрос");
ЗапросВнешний.Текст = 
    "ВЫБРАТЬ
    |	уатПутевойЛист.Ссылка КАК Ссылка,
    |	уатПутевойЛист.СпидометрВыезда КАК СпидометрВыезда,
    |	уатПутевойЛист.СпидометрВозвращения КАК СпидометрВозвращения
    |ИЗ
    |	Документ.уатПутевойЛист КАК уатПутевойЛист
    |ГДЕ
    |	уатПутевойЛист.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

ЗапросВнешний.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаОтчета));
ЗапросВнешний.УстановитьПараметр("КонецПериода", КонецДня(ДатаОтчета));

РезультатЗапроса = ЗапросВнешний.Выполнить();

Важный момент: если вы используете NewObject("Запрос") через объект соединения, 1С автоматически будет искать таблицы в метаданных той базы, к которой вы подключились.

Шаг 3. Обработка результатов и преобразование типов

Выясним причину распространенной ошибки «Неверное имя колонки» при попытке добавить данные в ТаблицаЗначений. Ошибка возникает, если программист пытается передать в метод Добавить() объект метаданных вместо строки с именем.

Также помните, что ссылки, полученные из внешней базы, «непонятны» для текущей базы. Если вы просто выгрузите результат во внутреннюю таблицу, вы получите либо пустые значения, либо ошибки. Нам нужно преобразовать все данные в простые типы: Число, Строка, Дата или Булево.

Разберем алгоритм выгрузки данных:


// Создаем локальную таблицу значений в текущей базе
ТЗ_Локальная = Новый ТаблицаЗначений;
ТЗ_Локальная.Колонки.Добавить("СпидометрВыезда", Новый ОписаниеТипов("Число"));
ТЗ_Локальная.Колонки.Добавить("СпидометрВозвращения", Новый ОписаниеТипов("Число"));
ТЗ_Локальная.Колонки.Добавить("Пробег", Новый ОписаниеТипов("Число"));
ТЗ_Локальная.Колонки.Добавить("ИдентификаторДокумента", Новый ОписаниеТипов("Строка"));

// Выбираем данные из внешнего результата
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    НоваяСтрока = ТЗ_Локальная.Добавить();
    НоваяСтрока.СпидометрВыезда = Выборка.СпидометрВыезда;
    НоваяСтрока.СпидометрВозвращения = Выборка.СпидометрВозвращения;
    
    // Вычисляем разницу прямо при заполнении
    НоваяСтрока.Пробег = Выборка.СпидометрВозвращения - Выборка.СпидометрВыезда;
    
    // Получаем GUID ссылки как строку, чтобы иметь связь с документом
    НоваяСтрока.ИдентификаторДокумента = Подключение.String(Выборка.Ссылка.UUID());
КонецЦикла;

Шаг 4. Передача данных в СКД (Внешний набор данных)

Теперь, когда у нас есть ТЗ_Локальная, заполненная чистыми данными, мы должны передать её в систему компоновки данных. Рассмотрим, как это сделать структурно:

  1. В схеме компоновки данных (СКД) создайте новый Набор данных - объект.
  2. В поле «Имя объекта содержащего данные» укажите, например, ВнешниеДанныеУАТ.
  3. Добавьте поля (СпидометрВыезда, СпидометрВозвращения и т.д.) с соответствующими типами.

В модуле отчета (в процедуре ПриКомпоновкеРезультата или в коде вызова отчета) пропишите связь:


СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);

// Помещаем нашу таблицу в структуру внешних наборов
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ВнешниеДанныеУАТ", ТЗ_Локальная);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Шаг 5. Завершение работы и очистка памяти

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

Используйте простую очистку переменной:


Подключение = Неопределено;
COMСоединитель = Неопределено;

Совет: если вам нужно выводить в отчет ссылки на объекты (например, на Автомобиль), которые существуют в обеих базах, передавайте не саму ссылку, а УникальныйИдентификатор. В базе-приемнике вы сможете найти объект методом Справочники.Автомобили.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)).

Таким образом, мы разобрали полный цикл работы с внешними данными: от безопасного подключения через COMConnector до корректного вывода преобразованных данных в отчет через механизмы СКД. Соблюдение этих этапов гарантирует высокую скорость работы отчета и отсутствие ошибок типов данных.

← На главную