Как создать элемент справочника с сохранением УИД через COM-соединение в 1С

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

При организации обмена данными между базами 1С через COM-соединение разработчики часто сталкиваются с задачей переноса ссылочных объектов с сохранением их исходных уникальных идентификаторов (GUID). Попытка напрямую передать значение типа УникальныйИдентификатор из базы-источника в метод менеджера справочника базы-приемника приводит к исключению:

«Произошла исключительная ситуация: Несоответствие типов (параметр номер '1')».

Разберем детально, почему возникает данная ошибка, как правильно передавать идентификаторы через границу COM-процессов и как корректно создавать элементы с предопределенной ссылкой.

Причина возникновения ошибки «Несоответствие типов»

Проанализируем механизм передачи объектов через COM-соединение. Любой объект сложного платформенного типа (включая УникальныйИдентификатор, СправочникСсылка и другие), созданный в контексте базы-источника, передается через границу процессов в виде внешней COM-обертки (IDispatch).

Когда мы вызываем метод Соединение.Справочники.ФизическиеЛица.ПолучитьСсылку(...), контекст базы-получателя ожидает собственный внутренний объект типа УникальныйИдентификатор. Менеджер справочника не может неявно преобразовать чужой COM-объект источника к своему внутреннему типу данных, что и вызывает ошибку типизации.

Кроме того, распространенной ошибкой является попытка передать полученную ссылку в качестве параметра методов СоздатьЭлемент() или СоздатьГруппу(). Согласно синтаксису платформы 1С:Предприятие, эти методы не принимают параметров. Назначение конкретной ссылки выполняется отдельно через специализированный метод объекта УстановитьСсылкуНового().

Пошаговый алгоритм создания элемента с сохранением УИД

Рассмотрим правильный и надежный порядок действий по переносу ссылки через COM-соединение.

  1. Преобразование идентификатора в примитивный тип: в базе-источнике получаем строковое представление GUID с помощью функции Строка() или XMLСтрока(). Строковые примитивы без искажений передаются через COM.
  2. Инициализация идентификатора в базе-приемнике: создаем внутренний объект УникальныйИдентификатор в контексте базы-получателя через вызов Соединение.NewObject().
  3. Формирование ссылки: получаем ссылку нужного справочника методом ПолучитьСсылку().
  4. Создание объекта и привязка ссылки: создаем новый объект справочника и вызываем метод УстановитьСсылкуНового() до момента его записи.

Пример программного кода

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


// 1. Получаем ссылку и ее строковый GUID в базе-источнике
СсылкаИсточник = Справочники.ФизическиеЛица.НайтиПоНаименованию("Иванов Иван Иванович");
Если Не ЗначениеЗаполнено(СсылкаИсточник) Тогда
    ВызватьИсключение "Объект в источнике не найден!";
КонецЕсли;

СтрокаУИД = Строка(СсылкаИсточник.УникальныйИдентификатор());

// 2. В контексте базы-приемника инициализируем новый УникальныйИдентификатор
УИДПолучатель = Соединение.NewObject("УникальныйИдентификатор", СтрокаУИД);

// 3. Получаем ссылку в базе-получателе
СсылкаПолучатель = Соединение.Справочники.ФизическиеЛица.ПолучитьСсылку(УИДПолучатель);

// 4. Проверяем, существует ли уже объект с такой ссылкой в базе-приемнике
ОбъектПолучатель = СсылкаПолучатель.ПолучитьОбъект();

Если ОбъектПолучатель = Неопределено Тогда
    // Объекта нет — создаем новый и привязываем ссылку
    ОбъектПолучатель = Соединение.Справочники.ФизическиеЛица.СоздатьЭлемент();
    ОбъектПолучатель.УстановитьСсылкуНового(СсылкаПолучатель);
КонецЕсли;

// 5. Заполняем реквизиты и записываем объект
ОбъектПолучатель.Наименование = СсылкаИсточник.Наименование;
// Заполнение остальных реквизитов...
ОбъектПолучатель.Записать();

Важные правила и ограничения при работе с УстановитьСсылкуНового

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

  1. Метод ПолучитьСсылку() не создает запись в базе данных: он лишь формирует ссылку заданного типа на основе переданного идентификатора. Проверить фактическое наличие элемента в базе можно вызовом Ссылка.ПолучитьОбъект().
  2. Применение только для новых объектов: метод УстановитьСсылкуНового() можно вызывать исключительно для объектов, у которых свойство ЭтоНовый() возвращает Истина. После первой записи объекта вызов этого метода вызовет исключение.
  3. Контроль уникальности: если в базе-получателе уже есть объект с таким же УникальныйИдентификатор, попытка записи нового объекта с дублирующейся ссылкой приведет к ошибке на уровне СУБД из-за нарушения первичного ключа таблицы. Всегда выполняйте проверку на существование объекта перед созданием нового.

Альтернативные способы передачи данных

Если требуется переносить большой массив справочников или документов, пообъектная работа через COM может работать медленно из-за сетевых накладных расходов на каждый вызов. Рассмотрим более производительные альтернативы:

  1. Сериализация через XDTO / FastInfoSet: в базе-источнике объект выгружается в XML с помощью СериализаторXDTO.ЗаписатьXML(), а в базе-получателе считывается через Соединение.СериализаторXDTO.ПрочитатьXML(). Этот механизм автоматически сохраняет оригинальные идентификаторы и состав реквизитов.
  2. Пакетная передача в экспортную процедуру: данные выгружаются в массив структур или JSON-строку и передаются единственным вызовом в экспортный метод общего модуля базы-приемника, где уже нативно создаются и записываются объекты.
  3. HTTP-сервисы и OData: современные интеграции на базе REST API позволяют оперировать строковыми GUID нативно, исключая необходимость использования COM-технологий.
← На главную