Как выгрузить табличную часть документа из 1С 8.3 в 1С 7.7 через COM-соединение?

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

При интеграции систем часто возникает задача переноса данных из более современной базы 1С:Предприятие 8.3 в рабочую конфигурацию на платформе 1С:Предприятие 7.7. Когда требуется загрузить табличную часть документа без изменения конфигурации источника, одним из популярных вариантов является использование прямого COM-соединения. Однако при взаимодействии двух разных платформ разработчики часто сталкиваются с ошибками доступа к реквизитам и передачей нераспознанных OLE-объектов. Разберем детально, как правильно построить алгоритм выгрузки, избежать типичных ошибок и перенести данные табличной части.

Анализ основных ошибок при работе с COM-объектами 1С 8.3 из 1С 7.7

Рассмотрим, почему при обращении к объектам 1С 8.3 из среды 1С 7.7 могут возникать ошибки выполнения:

  1. Передача ссылочных типов данных: Платформа 1С 7.7 не может напрямую работать со ссылочными типами данных платформы 8.3 (такими как СправочникСсылка или ДокументСсылка). При попытке прочитать реквизит Сотрудник среда 7.7 получает OLE-объект, строковое представление которого не совпадает с наименованием, а поиск по нему в базе 7.7 невозможен. Через COM-соединение необходимо передавать только примитивные типы: строку, число или дату.
  2. Попытка использовать методы платформы 7.7 для объектов 8.3: Таблица значений, возвращаемая методом Выгрузить() объекта Запрос платформы 8.3, является объектом восьмой версии. Соответственно, методы 1С 7.7 (например, ВыбратьСтроки() или ПолучитьСтроку()) у нее отсутствуют. Доступ к строкам таблицы значений 1С 8.3 осуществляется по индексу с помощью метода Получить(Индекс), где нумерация строк начинается с 0.
  3. Отсутствие позиционирования на строке таблицы значений: Обращение вида ТЗ.Размер вызывает ошибку «Поле агрегатного объекта не обнаружено», так как реквизиты принадлежат конкретной строке таблицы, а не самому объекту ТаблицаЗначений. Сначала необходимо получить строку через СтрокаТЗ = ТЗ.Получить(Ном), а затем считывать поля.
  4. Тяжелые вложенные запросы в цикле: Выполнение запроса внутри цикла выборки документов без передачи параметров отбора по конкретному документу приводит к тому, что на каждом шаге запрос заново читает всю таблицу базы данных, создавая колоссальную нагрузку на систему.

Решение 1: Выгрузка данных через оптимизированный COM-запрос

Проанализируем наиболее эффективный вариант: получение готовых данных табличной части с разыменованием всех ссылочных полей прямо в тексте запроса к базе 1С 8.3. В таком подходе мы сразу получаем примитивные типы (наименование сотрудника, числовые значения начислений), что исключает ошибки передачи OLE-ссылок.

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


V83 = СоздатьОбъект("V83.COMConnector");
Попытка
    База8 = V83.Connect("File=""\\Server\Base8""; Usr=""Обмен""; Pwd=""Пароль"";");
    Сообщить("Подключение к 1С 8.3 успешно установлено.");
Исключение
    Предупреждение("Ошибка открытия базы 1С 8.3: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Запрос = База8.NewObject("Запрос");
Запрос.Текст = 
"ВЫБРАТЬ
|   Начисления.Ссылка.Номер КАК НомерДокумента,
|   Начисления.Ссылка.Дата КАК ДатаДокумента,
|   Начисления.НомерСтроки КАК НомерСтроки,
|   Начисления.Сотрудник.Наименование КАК СотрудникНаименование,
|   Начисления.Сотрудник.Код КАК СотрудникКод,
|   Начисления.Размер КАК Размер,
|   Начисления.Результат КАК Результат,
|   Начисления.ДатаНачала КАК ДатаНачала,
|   Начисления.ДатаОкончания КАК ДатаОкончания
|ИЗ
|   Документ.НачислениеЗарплатыРаботникамОрганизаций.Начисления КАК Начисления";

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

ВсегоСтрок = ТЗ.Количество();
Если ВсегоСтрок > 0 Тогда
    Для Ном = 0 По ВсегоСтрок - 1 Цикл
        СтрокаТЗ = ТЗ.Получить(Ном);
        
        ФИОСотрудника = СтрокаТЗ.СотрудникНаименование;
        Оклад         = СтрокаТЗ.Размер;
        Начислено     = СтрокаТЗ.Результат;
        
        // Поиск сотрудника в базе 1С 7.7 по наименованию
        СпрСотр = СоздатьОбъект("Справочник.Сотрудники");
        Если СпрСотр.НайтиПоНаименованию(ФИОСотрудника, 0, 1) = 1 Тогда
            НоваяСтрока();
            Сотрудник = СпрСотр.ТекущийЭлемент();
            ОкладПоДокументу = Оклад;
            СуммаНачисления  = Начислено;
        Иначе
            Сообщить("Сотрудник не найден в базе 7.7: " + ФИОСотрудника);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

// Освобождение COM-объекта
База8 = ПолучитьПустоеЗначение();
V83 = ПолучитьПустоеЗначение();

Решение 2: Прямой обход документов и табличных частей через выборку

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

Посмотрим на реализацию обхода в коде:


V83 = СоздатьОбъект("V83.COMConnector");
Попытка
    База8 = V83.Connect("File=""\\Server\Base8""; Usr=""Обмен""; Pwd=""Пароль"";");
Исключение
    Предупреждение("Не удалось подключиться к базе: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// Формируем строковые представления дат для выборки 8.3
ФорматНач = Формат(НачДата, "ДГГГГММДД") + "000000";
ФорматКон = Формат(КонДата, "ДГГГГММДД") + "235959";

ВыборкаДок = База8.Документы.НачислениеЗарплатыРаботникамОрганизаций.Выбрать(ФорматНач, ФорматКон);

// В 1С 7.7 булево Истина из COM транслируется в -1
Пока ВыборкаДок.Следующий() = -1 Цикл
    ТЧ_Начисления = ВыборкаДок.Начисления;
    КоличествоСтрокТЧ = ТЧ_Начисления.Количество();
    
    Для НомСтроки = 0 По КоличествоСтрокТЧ - 1 Цикл
        ТекущаяСтрокаТЧ = ТЧ_Начисления.Получить(НомСтроки);
        
        // Получаем примитивные типы через свойства COM-объекта
        СотрудникФИО = ТекущаяСтрокаТЧ.Сотрудник.Наименование;
        СуммаРазмер  = ТекущаяСтрокаТЧ.Размер;
        СуммаИтог    = ТекущаяСтрокаТЧ.Результат;
        
        НоваяСтрока();
        Сотрудник = СотрудникФИО;
        Оклад     = СуммаРазмер;
        Аванс     = СуммаИтог;
    КонецЦикла;
КонецЦикла;

База8 = ПолучитьПустоеЗначение();
V83 = ПолучитьПустоеЗначение();

Важные особенности и рекомендации по сопоставлению данных

Рассмотрим дополнительные технические нюансы, которые следует учитывать при выгрузке:

  1. Разрядность платформы: Платформа 1С 7.7 является строго 32-разрядным приложением. Для успешной инициализации V83.COMConnector на компьютере должна быть зарегистрирована 32-битная библиотека comcntr.dll соответствующей версии 1С 8.3.
  2. Очистка соединений и освобождение лицензий: COM-соединение удерживает клиентскую лицензию 1С 8 до момента уничтожения объекта. В 1С 7.7 после завершения импорта необходимо явно присваивать переменным соединения ПолучитьПустоеЗначение().
  3. Надежность сопоставления: Сопоставление только по ФИО (Сотрудник.Наименование) может приводить к ошибкам при наличии полных однофамильцев. Рекомендуется выгружать уникальные идентификаторы: ИНН, СНИЛС или код справочника.
  4. Оптимизация поиска в 1С 7.7: Вызов НайтиПоНаименованию на каждой итерации большого объема данных замедляет загрузку. Для ускорения процесса рекомендуется перед началом цикла загрузить весь справочник сотрудников 1С 7.7 в локальную таблицу значений или список значений и выполнять быстрый поиск в памяти.
← На главную