При интеграции двух информационных баз 1С через COM-соединение разработчики часто сталкиваются с ошибкой "Неправильные параметры" при выполнении запросов. Чаще всего это происходит при попытке передать во внешнюю базу ссылку на объект (документ, справочник) или коллекцию (массив, список значений), созданную в текущем сеансе. Разберем подробно, почему возникает эта проблема и какими способами можно организовать корректную передачу данных.
Основная техническая сложность заключается в том, что объекты, созданные в контексте одной информационной базы, не существуют в другой. Даже если структуры баз идентичны, Ссылка в базе-источнике — это всего лишь внутренний идентификатор, который не имеет смысла для базы-приемника. То же самое касается коллекций: Массив или СписокЗначений, созданные в вашей текущей базе, являются "чужими" для COM-соединения.
Через COM-интерфейс без дополнительных манипуляций можно передавать только примитивные типы:
Проанализируем самый простой вариант, который подходит, когда объекты в обеих базах синхронизированы по своим реквизитам. Вместо передачи ссылки мы передаем примитивные данные документа и ищем его в целевой базе по комбинации "Номер + Дата".
Рассмотрим пример кода:
Запрос = COMСоединение.NewObject("Запрос");
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ.РеализацияТоваровУслуг
|ГДЕ
| Номер = &Номер
| И Дата = &Дата";
Запрос.УстановитьПараметр("Номер", ДокументСсылка.Номер);
Запрос.УстановитьПараметр("Дата", ДокументСсылка.Дата);
Результат = Запрос.Выполнить();
Этот метод надежен, если вы уверены, что номера и даты документов в базах строго совпадают. Однако он не сработает, если в базе-приемнике используются другие префиксы или номера назначаются иначе.
Если необходимо найти именно тот же самый объект, который был передан, лучшим решением будет использование уникального идентификатора (GUID). Выясним, как правильно реализовать этот механизм. Нам нужно преобразовать ссылку в строку GUID в исходной базе, передать её, а на стороне приемника восстановить объект UUID.
Посмотрим на алгоритм действий:
СтрокаGUID = Строка(Ссылка.УникальныйИдентификатор());.UUID из строки и получаем ссылку.Пример реализации в коде:
СтрокаGUID = Строка(ИсходнаяСсылка.УникальныйИдентификатор());
// На стороне COM-соединения:
НужныйUUID = COMСоединение.NewObject("UUID", СтрокаGUID);
СсылкаВПриемнике = COMСоединение.Справочники.Номенклатура.ПолучитьСсылку(НужныйUUID);
// Теперь эту ссылку можно передавать в параметры запроса
Запрос = COMСоединение.NewObject("Запрос");
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаВПриемнике);
Часто требуется передать в запрос условие ГДЕ Ссылка В (&МассивСсылок). Попытка передать обычный массив 1С приведет к ошибке. Чтобы это заработало, коллекция должна быть создана внутри COM-соединения.
Разберем по шагам, как это сделать:
// 1. Создаем массив непосредственно в целевой базе
МассивДляЗапроса = COMСоединение.NewObject("Массив");
// 2. Наполняем его данными (предварительно восстановив ссылки, как в Способе 2)
Для Каждого ТекСтрока Из СписокGUIDов Цикл
ТекущийUUID = COMСоединение.NewObject("UUID", ТекСтрока);
ТекСсылка = COMСоединение.Справочники.Контрагенты.ПолучитьСсылку(ТекущийUUID);
МассивДляЗапроса.Добавить(ТекСсылка);
КонецЦикла;
// 3. Передаем массив в запрос
Запрос = COMСоединение.NewObject("Запрос");
Запрос.Текст = "ВЫБРАТЬ Наименование ИЗ Справочник.Контрагенты ГДЕ Ссылка В (&Массив)";
Запрос.УстановитьПараметр("Массив", МассивДляЗапроса);
Проанализируем ситуацию, когда данных очень много. Перебор тысяч GUID-ов в цикле может быть медленным из-за накладных расходов на каждый вызов через COM. В этом случае эффективнее использовать сериализацию.
Вы можете преобразовать массив ссылок в XML-строку на стороне источника с помощью СериализаторXDTO.ЗаписатьXML(), передать одну длинную строку, а на стороне приемника выполнить обратную операцию. Это значительно ускоряет работу при больших объемах данных, так как минимизирует количество обращений между процессами.
При работе с большими объемами данных и сложными запросами через COM следует учитывать еще несколько моментов:
ValueTable (через NewObject("ValueTable")), наполнить её примитивными типами, а затем передать её в менеджер временных таблиц запроса.XMLСтрока(Ссылка). Это стандартный способ платформы для получения уникального строкового идентификатора объекта.Подводя итог, помните: всегда создавайте объекты запросов и коллекций в той базе, в которой вы собираетесь их исполнять. Это золотое правило избавит вас от большинства ошибок при работе через COM-соединение.