При организации интеграции между устаревшими и современными конфигурациями на платформе 1С:Предприятие разработчики часто сталкиваются с необходимостью прямого обмена данными. Одним из наиболее популярных сценариев является перенос данных из базы 1С 8.3 в базу 1С 7.7 (или наоборот) с использованием технологии OLE (COM-соединения). В процессе реализации такого обмена часто возникает задача сопоставления объектов. Лучшим инструментом для этого служит уникальный идентификатор (GUID) объекта базы-источника. Однако при попытке получить ссылку по известному строковому представлению уникального идентификатора в OLE-контексте 1С 8.3 разработчики регулярно сталкиваются с неприятной ошибкой: «Недопустимое значение параметра (параметр номер '1')». В этой статье мы подробно разберем, почему возникает эта ошибка, как ее оперативно исправить и какие альтернативные, более производительные способы работы с уникальными идентификаторами существуют.
Рассмотрим ситуацию, в которой оказывается разработчик. На стороне 1С 7.7 выполняется код, который инициализирует OLE-соединение с базой 1С 8.3 (переменная Обмен1). Задача состоит в том, чтобы по строковому представлению уникального идентификатора, сохраненному в 1С 7.7, восстановить полноценную ссылку на объект в 1С 8.3. Для этого пишется следующий код:
ОбъектУИД_83 = Обмен1.NewObject("УникальныйИдентификатор", тКонтрагентыФорма.УИД);
При выполнении этой строки платформа 1С 8.3 выбрасывает исключение с сообщением о недопустимом значении параметра. Почему так происходит? Выясним причину глубже. Дело в том, что конструктор объекта УникальныйИдентификатор в 1С 8.3 ожидает на входе строго форматированную строку длиной ровно 36 символов, соответствующую стандарту RFC 4122 (например, "12345678-1234-1234-1234-1234567890ab").
При передаче строковых переменных из 1С 7.7 через COM-соединение тип данных может неявно преобразовываться или дополняться концевыми пробелами. В 1С 7.7 строковые реквизиты справочников или колонок таблиц значений имеют фиксированную длину. Если длина поля составляет, к примеру, 50 символов, а длина УИД — 36 символов, то при считывании значения переменная будет автоматически дополнена 14 пробелами справа. Конструктор УникальныйИдентификатор в 1С 8.3 не умеет самостоятельно отбрасывать лишние пробелы и сразу же возвращает ошибку о неверном формате параметра.
Самым простым и быстрым решением является принудительная очистка строки от концевых пробелов и явное преобразование типа значения на стороне OLE-сервера. Разберем по шагам, как это реализовать. Нам необходимо гарантировать, что в конструктор передается строка без лишних символов.
Во-первых, мы можем использовать функцию СокрЛП() непосредственно на стороне 1С 7.7 перед отправкой значения в COM-соединение. Посмотрим на пример кода:
ОчищеннаяСтрокаУИД = СокрЛП(тКонтрагентыФорма.УИД);
ОбъектУИД_83 = Обмен1.NewObject("УникальныйИдентификатор", ОчищеннаяСтрокаУИД);
Во-вторых, если строка была получена напрямую из объекта 1С 8.3 в процессе обмена, надежнее всего использовать сериализацию или явное приведение типов на стороне OLE-сервера. Для этого отлично подходят функции string() или XMLString() контекста 1С 8.3. Проанализируем пример кода:
// Использование встроенной функции строкового преобразования OLE-сервера
СтрокаУИД_83 = Обмен1.String(Контрагент83.УникальныйИдентификатор());
ОбъектУИД_83 = Обмен1.NewObject("УникальныйИдентификатор", СтрокаУИД_83);
При таком подходе платформа 1С 8.3 гарантированно получает строку нужного формата, и объект УникальныйИдентификатор создается без каких-либо ошибок.
Создание COM-объектов через метод NewObject — это достаточно ресурсоемкая операция, особенно если перенос данных осуществляется в цикле для тысяч элементов справочника. Мы можем оптимизировать этот процесс и полностью отказаться от ручного создания объекта УникальныйИдентификатор. Для этого воспользуемся мощным механизмом XML-сериализации, встроенным в 1С 8.3.
Каждая ссылка в 1С 8.3 имеет свое XML-представление, которое строится на основе типа объекта и его GUID. Мы можем напрямую преобразовать строковый идентификатор из 1С 7.7 в готовую ссылку 1С 8.3. Рассмотрим подробнее, как это сделать:
// Получаем тип ссылки на стороне 1С 8.3
ТипКонтрагента8 = Обмен1.XMLTypeOf(Обмен1.Справочники.Контрагенты.ПустаяСсылка());
// Напрямую восстанавливаем ссылку по строковому УИД
СтрокаУИД = СокрЛП(тКонтрагентыФорма.УИД);
Ссылка8 = Обмен1.XMLValue(Обмен1.FromXMLType(ТипКонтрагента8), СтрокаУИД);
Этот метод работает значительно быстрее, так как преобразование типов происходит на уровне платформенных механизмов сериализации без создания промежуточных COM-объектов в памяти. Настоятельно рекомендуем использовать именно этот способ при массовом поиске ссылок.
Если в вашем коде инициализация OLE-соединения происходит через V83.Application, мы советуем пересмотреть архитектуру решения в пользу V83.COMConnector. Разберем ключевые отличия:
V83.Application запускает полноценное клиентское приложение 1С:Предприятие со всеми его интерфейсными механизмами, модулями управляемого приложения и обработчиками событий при старте. Это требует огромного количества оперативной памяти. В свою очередь, V83.COMConnector запускает только облегченный внутрипроцессный сервер, не расходующий память на отрисовку интерфейса.COMConnector выполняются в разы быстрее, так как отсутствуют задержки на взаимодействие с оконной системой Windows.Посмотрим на пример правильного подключения и поиска ссылки по УИД с использованием COMConnector:
// Инициализация легкого COM-соединения
Инициализатор = СоздатьОбъект("V83.COMConnector");
СтрокаПодключения = "File=""C:\Base83"";Usr=""Администратор"";Pwd="""";";
Обмен1 = Инициализатор.Connect(СтрокаПодключения);
// Быстрый поиск ссылки
СтрокаУИД = СокрЛП(тКонтрагентыФорма.УИД);
ОбъектУИД_83 = Обмен1.NewObject("УникальныйИдентификатор", СтрокаУИД);
// Получение ссылки с использованием англоязычного аналога метода
Ссылка8 = Обмен1.Справочники.Контрагенты.GetRef(ОбъектУИД_83);
При разработке интеграционных решений через OLE/COM крайне важно учитывать языковые настройки платформы. В некоторых случаях русскоязычные имена методов (такие как ПолучитьСсылку()) могут вызывать ошибки во внешней среде, особенно если операционная система или платформа имеют отличную от русской локализацию. Для обеспечения максимальной надежности кода рекомендуется использовать англоязычные аналоги методов 1С. Например, вместо метода ПолучитьСсылку() безопаснее написать GetRef(), а вместо УникальныйИдентификатор можно использовать UUID:
// Безопасный вызов на любом языковом пакете
ОбъектУИД_83 = Обмен1.NewObject("UUID", СокрЛП(тКонтрагентыФорма.УИД));
Ссылка8 = Обмен1.Справочники.Contragents.GetRef(ОбъектУИД_83);
Иногда перед отправкой данных в 1С 8.3 разработчику необходимо сгенерировать новый уникальный идентификатор прямо на стороне 1С 7.7. Делать для этого постоянные вызовы OLE-сервера (Обмен1.NewObject("UUID")) крайне непроизводительно. Мы можем сгенерировать полноценный GUID стандарта RFC 4122 средствами операционной системы Windows или встроенных компонент 1С 7.7.
Посмотрим на пример генерации GUID через системную библиотеку Windows Scriptlet.TypeLib:
Функция ПолучитьНовыйGUID()
TypeLib = СоздатьОбъект("Scriptlet.TypeLib");
// Извлекаем GUID и убираем фигурные скобки {}
НашGUID = Сред(TypeLib.Guid, 2, 36);
Возврат ВРег(НашGUID);
КонецФункции
Если в вашей конфигурации 1С 7.7 подключена и используется стандартная библиотека v7plus.dll, вы можете задействовать ее встроенный объект для работы с системной информацией:
Функция ПолучитьGUIDЧерезV7Plus()
Попытка
ЗагрузитьВнешнююКомпоненту("v7plus.dll");
Инфо = СоздатьОбъект("AddIn.V7SysInfo");
Возврат Инфо.СоздатьGUID();
Исключение
Возврат "";
КонецПопытки;
КонецФункции
Оба метода позволяют мгновенно генерировать валидные уникальные идентификаторы на стороне 1С 7.7, которые без проблем будут приняты базой 1С 8.3 при последующей загрузке данных.
Если ваша база-источник 1С 8.3 работает на современной версии платформы (начиная с релиза 8.3.22), вам доступно существенное улучшение — встроенная функция УникальныйИдентификатор() в языке запросов. Это означает, что при выгрузке данных вам больше не нужно в цикле обходить выборку объектов для получения их строковых GUID. Вы можете получить готовую таблицу соответствий со строковыми УИД одним запросом на стороне 1С 8.3 и передать ее в 1С 7.7 в виде готового пакета данных. Это кардинально ускоряет процесс сопоставления и переноса информации.
Мы детально проанализировали проблему возникновения ошибки «Недопустимое значение параметра» при передаче уникальных идентификаторов через OLE. Мы выяснили, что основной причиной является неявное искажение строковых типов при передаче из 1С 7.7. Для успешного решения этой проблемы достаточно придерживаться нескольких простых правил:
СокрЛП() перед передачей в конструктор 1С 8.3.XMLValue вместо ручного создания объектов УникальныйИдентификатор для повышения производительности интеграции.V83.COMConnector вместо тяжеловесного V83.Application.GetRef, UUID) для обеспечения кроссплатформенной надежности кода.Применение этих методик на практике позволит вам создать быстрое, стабильное и отказоустойчивое решение для обмена данными между платформами 1С 7.7 и 1С 8.3.