При обмене данными между двумя базами 1С часто возникает задача сохранить идентичность объектов. Лучший способ сделать это — перенести объект с тем же Уникальным Идентификатором (UUID/GUID). Однако при реализации этой задачи через COM-соединение программисты часто сталкиваются с неочевидными ошибками. В этой статье мы разберем, как правильно передавать UUID, обходить ограничения мутабельности и работать с метаданными объектов во внешней базе.
Типичная ошибка новичка заключается в попытке напрямую передать объект УникальныйИдентификатор из внешней базы в локальный конструктор. Рассмотрим ситуацию: мы получаем ссылку на контрагента из внешней базы и хотим создать такую же в текущей. Если написать код напрямую, как в примере ниже, платформа выдаст ошибку "Неверный параметр":
УидВоВнешнейБазе = КонтрСоб.Ссылка.УникальныйИдентификатор();
// Ошибка произойдет здесь:
УидВЭтойБазе = Новый УникальныйИдентификатор(Строка(УидВоВнешнейБазе));
Причина заключается в том, что COM-объект, возвращаемый внешней базой, не является стандартной строкой или типом, который локальный конструктор УникальныйИдентификатор может распознать корректно. Выясним причину: внешняя база передает COM-объект, и прямое преобразование Строка() может отработать не так, как ожидается в контексте разных сессий.
Для гарантированного получения строкового представления идентификатора следует использовать механизм XML. Однако здесь есть важный нюанс. Если вызвать локальную функцию XMLСтрока() и передать ей идентификатор из внешней базы, мы получим ошибку "Ошибка преобразования данных XML".
Правильное решение: вызывать метод XMLСтрока непосредственно через объект подключения к внешней базе. Проанализируем правильную конструкцию:
// БазаОткрыта - это наше COM-соединение (V83.COMConnector)
УидСтрокой = БазаОткрыта.XMLСтрока(КонтрСоб.Ссылка.УникальныйИдентификатор());
УидВЭтойБазе = Новый УникальныйИдентификатор(УидСтрокой);
НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку(УидВЭтойБазе));
Этот метод позволяет корректно извлечь строковое значение GUID из контекста внешней базы и использовать его для создания ссылки в текущей базе.
При работе с COM-соединением часто возникает ошибка: "Проверка мутабельных значений на заполненность не поддерживается". Разберем, почему это происходит. Мутабельные значения — это сложные объекты (таблицы значений, структуры, ссылки), которые могут изменяться. Передавать их "через границу" COM-соединения в локальные функции 1С нельзя.
Рассмотрим пример кода, вызывающий ошибку:
Если ЗначениеЗаполнено(Источник[НаимРеквизита]) Тогда
// Ошибка: Источник[НаимРеквизита] — это мутабельное значение из внешней базы
КонецЕсли;
Чтобы избежать этой проблемы, мы должны выполнять проверку на стороне той базы, которой принадлежит объект. Используем объект соединения:
Если БазаОткрыта.ЗначениеЗаполнено(Источник[НаимРеквизита]) Тогда
// Так проверка отработает корректно
КонецЕсли;
Это золотое правило работы с COM: все операции над объектами внешней базы (проверка заполненности, поиск, получение метаданных) должны выполняться через методы этой самой базы.
При универсальном переносе данных нам часто нужно знать структуру объекта "на лету". Например, есть ли у справочника владелец? Если мы попытаемся обратиться к метаданным напрямую, мы снова можем столкнуться с трудностями интерпретации типов.
Посмотрим на пример, как узнать количество владельцев справочника во внешней базе:
// СправочникОбъект получен из внешней базы
КоличествоВладельцев = СправочникОбъект.Метаданные().Владельцы.Количество();
Если КоличествоВладельцев > 0 Тогда
// Логика обработки владельца
КонецЕсли;
Этот код позволяет динамически определять, нужно ли заполнять реквизит Владелец при создании нового объекта в целевой базе. Если владельцев несколько, вы можете перебором получить их типы через коллекцию Владельцы.
Рассмотрим несколько критических моментов, которые помогут избежать ошибок при записи объектов в SQL-базу:
УстановитьСсылкуНового() работает исключительно до первого вызова Записать(). Если объект уже существует в базе, сменить его UUID программно невозможно.UUID приведет к критической ошибке СУБД.Подводя итог, можно сказать, что перенос данных с сохранением UUID — это мощный инструмент синхронизации, но он требует аккуратного обращения с контекстами выполнения. Всегда приводите сложные типы к примитивным (строкам или числам) при передаче через COM и используйте методы внешней базы для анализа ее же объектов.