Как получить таблицу значений из 1С 8 в 1С 7.7 при подключении через COM/OLE без промежуточных файлов?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции конфигураций 1С:Предприятия 7.7 и 8.x часто возникает задача: вызвать экспортную функцию в базе 1С 8 через COM-соединение (или OLE Automation) и получить результат в виде таблицы значений в коде 1С 7.7. Главное требование при этом — избежать сохранения данных во временные файлы на диске.

Разберем особенности взаимодействия двух платформ, выясним причины возможных сложностей и рассмотрим рабочие способы передачи табличных данных в оперативную память 1С 7.7.

Особенности взаимодействия 1С 7.7 и 1С 8 через COM/OLE

Объект ТаблицаЗначений в 1С 8 и 1С 7.7 имеет принципиально разную внутреннюю структуру. Напрямую присвоить объект одной платформы переменной другой платформы невозможно. При вызове экспортной функции восьмерки база 1С 7.7 получает лишь ссылку на COMОбъект (или OLE-объект).

При работе с COM-объектами восьмерки из семерки необходимо учитывать следующие правила:

  1. Индексация элементов: в платформе 1С 8 нумерация строк и колонок в коллекциях начинается с 0, тогда как в 1С 7.7 — с 1.
  2. Синтаксис обхода: в 1С 7.7 отсутствует конструкция Для Каждого ... Из ... Цикл, а также обращение к строкам по квадратным скобкам (ТЗ[Индекс]). Обращение выполняется через методы объекта: Получить(Индекс) или Колонки.Получить(Индекс).
  3. Приведение типов: ссылочные объекты 1С 8 (справочники, документы) при передаче в 1С 7.7 остаются чужеродными COM-объектами. На стороне 8-ки их необходимо приводить к базовым примитивным типам: Строка, Число, Дата или Булево.
  4. Производительность COM-вызовов: каждое обращение к ячейке COM-объекта требует времени на межпроцессное взаимодействие (маршалинг). Поячеечный перебор сотен и тысяч строк может выполняться медленно, поэтому для больших объемов данных применяются альтернативные методы передачи в памяти.

Способ 1. Прямой перебор колонок и строк COM-объекта

Рассмотрим стандартный вариант для небольших таблиц. В 1С 7.7 создаем локальный объект ТаблицаЗначений, считываем структуру колонок из COM-объекта восьмерки и в цикле переносим значения строк.


// В 1С 7.7 подключаемся к 1С 8 и вызываем функцию
База8 = СоздатьОбъект("V83.COMConnector");
Соединение8 = База8.Connect("Srvr=""Server1C"";Ref=""Base8"";Usr=""User"";Pwd=""Pass"";");

// Получаем COM-объект ТаблицаЗначений из экспортной функции
ТЗ8 = Соединение8.МойЭкспортныйМодуль.ПолучитьТаблицуДанных();

// Создаем локальную таблицу значений в 1С 7.7
ТЗ7 = СоздатьОбъект("ТаблицаЗначений");

// Переносим колонки (в 1С 8 индекс колонок начинается с 0)
КолКолонок = ТЗ8.Колонки.Количество();
Для к = 0 По КолКолонок - 1 Цикл
    Колонка8 = ТЗ8.Колонки.Получить(к);
    ТЗ7.НоваяКолонка(Колонка8.Имя);
КонецЦикла;

// Переносим строки
КолСтрок = ТЗ8.Количество();
Для с = 0 По КолСтрок - 1 Цикл
    Строка8 = ТЗ8.Получить(с);
    ТЗ7.НоваяСтрока();
    Для к = 0 По КолКолонок - 1 Цикл
        ИмяКолонки = ТЗ8.Колонки.Получить(к).Имя;
        ЗначениеЯчейки = Строка8.Получить(к);
        ТЗ7.УстановитьЗначение(ТЗ7.НомерСтроки, ИмяКолонки, ЗначениеЯчейки);
    КонецЦикла;
КонецЦикла;

Способ 2. Передача текстового потока с разделителями (CSV в памяти)

Если таблица содержит тысячи строк, прямой перебор COM-ячеек будет работать долго. Оптимальное решение без создания файлов — сформировать в функции 1С 8 одну текстовую строку с разделителями колонок (например, символ табуляции) и строк (символ перевода строки), передать ее в 1С 7.7 за один COM-вызов и разобрать в локальную таблицу значений.

Посмотрим на реализацию функции на стороне 1С 8:


// Экспортная функция в общем модуле 1С 8
Функция ПолучитьТаблицуТекстом() Экспорт
    ТЗ = СформироватьДанные(); // Ваша таблица значений
    
    ТекстовыйБуфер = "";
    Для Каждого Стр Из ТЗ Цикл
        СтрокаТекста = "";
        Для Каждого Кол Из ТЗ.Колонки Цикл
            СтрокаТекста = СтрокаТекста + ?(СтрокаТекста = "", "", Символы.Таб) + Строка(Стр[Кол.Имя]);
        КонецЦикла;
        ТекстовыйБуфер = ТекстовыйБуфер + ?(ТекстовыйБуфер = "", "", Символы.ПС) + СтрокаТекста;
    КонецЦикла;
    
    Возврат ТекстовыйБуфер;
КонецФункции

Теперь разберем, как быстро прочитать полученный текст в 1С 7.7:


// В 1С 7.7 принимаем строку
ТекстДанных = Соединение8.МойЭкспортныйМодуль.ПолучитьТаблицуТекстом();

ТЗ7 = СоздатьОбъект("ТаблицаЗначений");
ТЗ7.НоваяКолонка("Код");
ТЗ7.НоваяКолонка("Наименование");
ТЗ7.НоваяКолонка("Сумма");

ВсегоСтрок = СтрКоличествоСтрок(ТекстДанных);
Для Ном = 1 По ВсегоСтрок Цикл
    ТекущаяСтрока = СтрПолучитьСтроку(ТекстДанных, Ном);
    Если ПустаяСтрока(ТекущаяСтрока) = 0 Тогда
        ТЗ7.НоваяСтрока();
        
        // Разбираем строку по табуляции
        СтрПозиция = Найти(ТекущаяСтрока, Симв(9));
        ТЗ7.Код = Лев(ТекущаяСтрока, СтрПозиция - 1);
        ТекущаяСтрока = Сред(ТекущаяСтрока, СтрПозиция + 1);
        
        СтрПозиция = Найти(ТекущаяСтрока, Симв(9));
        ТЗ7.Наименование = Лев(ТекущаяСтрока, СтрПозиция - 1);
        ТЗ7.Сумма = Число(Сред(ТекущаяСтрока, СтрПозиция + 1));
    КонецЕсли;
КонецЦикла;

Способ 3. Использование Recordset (ADODB) в памяти

Еще один способ — создание отсоединенного набора данных ADODB.Recordset. Обе платформы поддерживают работу с COM-объектами Windows Data Access Components (ADO).

  1. На стороне 1С 8 создается объект Новый COMОбъект("ADODB.Recordset").
  2. С помощью метода Fields.Append описываются поля таблицы и заполняются строки.
  3. Объект передается в 1С 7.7, где обходится стандартным курсором через метод MoveNext().

Итоги

Для небольших таблиц значений (до нескольких сотен строк) достаточно использовать прямой перебор строк COM-объекта через методы Колонки.Получить(к) и Получить(с). Для больших объемов данных рекомендуется возвращать сериализованную строку (CSV/TSV или XML в памяти), что позволяет свести передачу данных к одному быстрому COM-обращению.

← На главную