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