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