Как передавать сложные типы данных и реквизиты через COM-соединение в 1С?

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

Передача данных между базами 1С через COM-соединение — это классическая задача, с которой сталкиваются разработчики при интеграции систем. Если передача простых типов (строка, число, дата) не вызывает затруднений, то работа со ссылочными типами, такими как Справочники или Перечисления, часто ставит новичков в тупик. Разберем подробно, как правильно организовать этот процесс, на примере обмена между «Бухгалтерией предприятия 3.0» и «Управлением торговлей 11».

Понимание природы COM-объектов

Прежде всего, проанализируем важный нюанс: когда мы создаем COM-соединение, мы получаем доступ к объектам другой базы, но эти объекты не являются «родными» для нашей текущей базы. Это так называемые «прокси-объекты». Мы не можем просто присвоить реквизиту ВидНоменклатуры в базе-приемнике ссылку из базы-источника. Нам необходимо найти соответствующий объект в базе-приемнике или создать его там.

Способ 1. Поиск по наименованию

Это самый простой и интуитивно понятный способ. Рассмотрим ситуацию, когда нам нужно передать номенклатуру и заполнить её вид. Мы будем использовать метод НайтиПоНаименованию через объект Соединение.

Разберем алгоритм действий по шагам:

  1. Получаем наименование нужного объекта из базы-источника.
  2. Обращаемся к менеджеру справочника в базе-приемнике через COM.
  3. Выполняем поиск.
  4. Если объект не найден, принимаем решение: создать новый или оставить поле пустым.

Посмотрим на пример кода:


// Предположим, Соединение уже установлено
НаименованиеВида = ОбъектИсточник.ВидНоменклатуры.Наименование;

// Ищем вид номенклатуры в базе-приемнике (УТ)
ВидНоменклатурыУТ = Соединение.Справочники.ВидыНоменклатуры.НайтиПоНаименованию(НаименованиеВида);

// Проверяем, нашли ли мы что-нибудь
Если Соединение.XMLСтрока(ВидНоменклатурыУТ) = Соединение.XMLСтрока(Соединение.Справочники.ВидыНоменклатуры.ПустаяСсылка()) Тогда
    // Если не нашли, можем создать новый элемент
    НовыйВид = Соединение.Справочники.ВидыНоменклатуры.СоздатьЭлемент();
    НовыйВид.Наименование = НаименованиеВида;
    // Заполняем другие обязательные реквизиты для УТ 11
    НовыйВид.ТипНоменклатуры = Соединение.Перечисления.ТипыНоменклатуры.Товар;
    НовыйВид.Записать();
    ВидНоменклатурыУТ = НовыйВид.Ссылка;
КонецЕсли;

// Теперь подставляем найденную или созданную ссылку в объект номенклатуры
НоменклатураОбъектУТ.ВидНоменклатуры = ВидНоменклатурыУТ;

Способ 2. Надежный поиск по уникальному идентификатору (GUID)

Поиск по наименованию часто подводит: пользователи могут изменить название, или в базе могут оказаться дубли. Проанализируем более профессиональный подход — использование UUID (уникального идентификатора). Каждый объект в 1С имеет свой уникальный ключ, который остается неизменным.

Рассмотрим, как передать ссылку через GUID:


// В базе-источнике получаем строковое представление GUID
СтрокаGUID = Строка(ОбъектИсточник.УникальныйИдентификатор());

// В базе-приемнике через COM создаем объект GUID и ищем по нему ссылку
СсылкаПриемник = Соединение.Справочники.Номенклатура.ПолучитьСсылку(Соединение.NewObject("Guid", СтрокаGUID));

// Проверяем существование объекта в приемнике
ОбъектСуществует = Соединение.Справочники.Номенклатура.Выбрать(СсылкаПриемник).Следующий();

Если Не ОбъектСуществует Тогда
    // Логика создания нового объекта, если по GUID ничего не найдено
КонецЕсли;

Особенности передачи Перечислений

С Перечислениями ситуация иная: их нельзя создать программно, они жестко заданы в конфигурации. Чтобы передать значение перечисления (например, СтавкаНДС), мы должны сопоставить их по имени значения.

Выясним, как это сделать правильно:


// Получаем имя значения перечисления в источнике (например, "НДС20")
ИмяЗначения = ОбъектИсточник.СтавкаНДС.Метаданные().Имя; 

// Находим аналогичное значение в базе-приемнике
СтавкаНДСПриемник = Соединение.Перечисления.СтавкиНДС[ИмяЗначения];

// Присваиваем
НовыйОбъектУТ.СтавкаНДС = СтавкаНДСПриемник;

Важно: Если имена значений перечислений в разных конфигурациях (БП и УТ) различаются, вам придется написать таблицу соответствия (например, через оператор Если ... ИначеЕсли или используя Соответствие).

Оптимизация: использование кэширования (Соответствия)

Проанализируем ситуацию: если вы загружаете 1000 товаров, и для каждого товара вызываете НайтиПоНаименованию через COM, ваш обмен будет работать крайне медленно. Каждое обращение через точку в COM-объекте — это длительный сетевой вызов.

Для ускорения работы рекомендуем использовать объект Соответствие для кэширования уже найденных ссылок:


КэшВидов = Новый Соответствие;

Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
    СсылкаИсточник = СтрокаТовара.ВидНоменклатуры;
    
    // Ищем в локальном кэше, чтобы не дергать COM-соединение лишний раз
    ВидПриемник = КэшВидов.Получить(СсылкаИсточник);
    
    Если ВидПриемник = Неопределено Тогда
        // Только если в кэше нет, идем в COM
        ВидПриемник = Соединение.Справочники.ВидыНоменклатуры.НайтиПоНаименованию(СсылкаИсточник.Наименование);
        КэшВидов.Вставить(СсылкаИсточник, ВидПриемник);
    КонецЕсли;
    
    // Используем ВидПриемник для записи товара
КонецЦикла;

Типичные ошибки при работе с COM

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

Таким образом, мы рассмотрели основные механизмы передачи сложных реквизитов. Главное правило — всегда помнить, что в базе-приемнике вы работаете с «чужими» объектами, которые требуют предварительного поиска или создания перед присваиванием в реквизиты.

← На главную