При реализации прямого обмена данными между двумя конфигурациями 1С (например, Управление торговлей 11 и Бухгалтерия предприятия 3.0) через механизм COM-соединения программисты часто сталкиваются с необходимостью синхронизации объектов по их внутренним идентификаторам. Это критически важно для того, чтобы при повторной выгрузке документ не дублировался, а обновлялся. Однако попытка напрямую передать УникальныйИдентификатор в метод УстановитьСсылкуНового часто заканчивается ошибкой «Несоответствие типов». Разберем подробно, почему это происходит и как правильно организовать процесс.
Рассмотрим ситуацию, описанную в теме. Разработчик пытается создать объект в базе-приемнике через COM и присвоить ему идентификатор из базы-источника. Ошибка возникает в следующей строке:
НовыйДокумент.УстановитьСсылкуНового(НовыйГУИД);
Проблема заключается в том, что метод УстановитьСсылкуНового ожидает в качестве параметра объект типа Ссылка (например, ДокументСсылка.РеализацияТоваровУслуг), а не объект типа УникальныйИдентификатор. Даже если вы создали УникальныйИдентификатор внутри COM-соединения, он все равно остается лишь «заготовкой» для ссылки, но не самой ссылкой.
Когда мы работаем через COM, объекты базы-приемника являются для базы-источника COM-объектами. Платформа строго следит за типизацией, и передача «сырого» идентификатора вместо ссылки приводит к исключительной ситуации.
Для успешного присвоения идентификатора нам необходимо пройти путь из трех шагов: передать строковое представление ГУИД, восстановить его как объект идентификатора в целевой базе и превратить этот идентификатор в пустую ссылку нужного типа. Рассмотрим, как это реализовать на практике.
Проанализируем правильный код для базы-источника:
// 1. Получаем строковое представление ГУИД из текущей базы
СтрокаГУИД = Строка(ДокументСсылкаИсточник.УникальныйИдентификатор());
// 2. В COM-соединении создаем объект УникальныйИдентификатор из строки
КомУИД = СоединениеСБУХ.NewObject("УникальныйИдентификатор", СтрокаГУИД);
// 3. Формируем ссылку в базе-приемнике, используя менеджер документа
// ВАЖНО: ПолучитьСсылку() создает ссылку, которая еще не записана в БД
КомСсылка = СоединениеСБУХ.Документы.РеализацияТоваровУслуг.ПолучитьСсылку(КомУИД);
// 4. Создаем новый объект документа в базе-приемнике
НовыйДокумент = СоединениеСБУХ.Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// 5. Устанавливаем подготовленную ссылку
НовыйДокумент.УстановитьСсылкуНового(КомСсылка);
// Далее заполняем реквизиты и записываем
НовыйДокумент.ОбменДанными.Загрузка = Истина;
НовыйДокумент.Записать();
Разберем подробнее, что здесь происходит. Метод ПолучитьСсылку у менеджера документа в COM-базе возвращает объект типа Ссылка, который еще не существует в таблицах базы данных, но уже имеет жестко заданный УникальныйИдентификатор. Именно эту ссылку мы передаем в УстановитьСсылкуНового. Теперь, при выполнении метода Записать, система создаст запись в базе данных именно с тем ГУИДом, который мы передали.
Для повышения надежности передачи данных, особенно если версии платформ или конфигураций могут отличаться, рекомендуется использовать механизмы XML-сериализации. Это гарантирует, что строка идентификатора будет передана в стандартном формате без лишних пробелов или искажений.
Посмотрим на пример использования XMLСтрока:
// В базе источнике используем стандартную функцию
ТекстГУИД = XMLСтрока(ДокументСсылка);
// В базе приемнике (через COM) восстанавливаем
УИД_Приемник = СоединениеСБУХ.NewObject("УникальныйИдентификатор", ТекстГУИД);
СсылкаПриемник = СоединениеСБУХ.Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД_Приемник);
Этот подход считается более «чистым» в среде разработчиков 1С, так как он задействует встроенные механизмы платформы по работе со строковыми представлениями ссылочных типов.
Работа через COM-соединение накладывает ряд ограничений, о которых необходимо помнить при проектировании обмена:
Предупреждение или ОткрытьФорму), обмен упадет с ошибкой, так как COM-соединение работает в неинтерактивном режиме. Проверьте, чтобы в модулях стояли соответствующие проверки #Если Сервер или #Если ВнешнееСоединение.comcntrv8s.dll зарегистрирована в реестре именно для 64-битных приложений. Часто бывает, что код работает на компьютере разработчика, но выдает ошибку «Класс не зарегистрирован» на сервере.Как справедливо отмечено в обсуждении на форуме, COM-соединение — не единственный и не всегда лучший способ организации обмена «один к одному». Рассмотрим альтернативы, которые предлагает современная платформа 1С:
1. Универсальный формат Enterprise Data
Это стандартный механизм синхронизации, заложенный в типовые конфигурации (УТ 11, БП 3.0, ERP). Вместо написания кода для каждого реквизита, вы настраиваете правила сопоставления. Платформа сама заботится о передаче идентификаторов и контроле дублей. Это позволяет избежать «обвешивания» баз регламентными заданиями и дает возможность гибко настраивать фильтры выгрузки.
2. HTTP-сервисы и REST API
Вместо прямого подключения к базе, вы можете опубликовать HTTP-сервис в базе-приемнике. База-источник будет отправлять POST-запросы с данными в формате JSON. Это работает быстрее, не требует постоянного удержания лицензии и гораздо стабильнее при плохом интернет-соединении.
Пример структуры JSON для передачи документа:
{
"guid": "550e8400-e29b-41d4-a716-446655440000",
"date": "2023-10-27T10:00:00",
"number": "00000001",
"amount": 1500.50
}
3. OData (Автоматический REST-интерфейс)
В 1С можно включить встроенный интерфейс OData. Тогда для создания документа с определенным ГУИДом достаточно отправить один запрос к веб-серверу, указав в поле Ref_Key нужный идентификатор. Система сама создаст объект или обновит существующий.
Если вам необходимо быстро исправить существующий обмен через COM-соединение, используйте метод ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаГУИД)) на стороне базы-приемника. Это решит проблему несоответствия типов. Однако для новых проектов мы рекомендуем рассмотреть Enterprise Data или HTTP-сервисы, так как они обеспечивают более высокую стабильность и масштабируемость системы.