При организации интеграции между базами данных 1С с помощью внешнего COM-соединения разработчики часто сталкиваются с ошибками вида «Метод объекта не обнаружен (NewObject)» или невозможностью корректно передать текст и параметры запроса. Разберем по шагам, почему возникают подобные проблемы, как правильно инициализировать удаленные объекты и что делать в нестандартных ситуациях.
Рассмотрим типовую функцию подключения к удаленной базе данных по протоколу COM. Создание коннектора и получение ссылки на внешнюю базу выглядит следующим образом:
Функция ПолучитьПодключениеКОсновнойБД(Путь, ИмяПользователя, Пароль)
Если СокрЛП(Пароль) = "" Тогда
ПараметрыСоединения = "File=""" + Путь + """; Usr=""" + ИмяПользователя + """;";
Иначе
ПараметрыСоединения = "File=""" + Путь + """; Usr=""" + ИмяПользователя + """; Pwd=""" + Пароль + """;";
КонецЕсли;
Попытка
V83COMConnector = Новый COMОбъект("V83.COMConnector");
Base1C = V83COMConnector.Connect(ПараметрыСоединения);
Возврат Base1C;
Исключение
Сообщить("Ошибка подключения к внешней базе данных!");
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
Когда соединение успешно установлено, переменная Base1C хранит ссылку на контекст удаленной информационной базы. Однако при попытке вызвать конструктор запроса с передачей текста напрямую в метод NewObject (или НовыйОбъект) можно столкнуться с ошибкой обработки параметров либо потерей контекста.
Наиболее надежный и платформенно-независимый способ создания объекта Запрос во внешней базе через COM — это вызов конструктора без передачи строки запроса в качестве второго параметра с последующим заполнением свойства Текст. Проанализируем правильный пример кода:
Соединение = ПолучитьПодключениеКОсновнойБД(Объект.ПутьКБазеДанных, Объект.ИмяПользователя, Объект.Пароль);
Если Соединение = Неопределено Тогда
Сообщить("Не удалось подключиться к базе");
Возврат;
КонецЕсли;
// 1. Создаем объект без передачи параметров конструктора
ЗапросУдаленнойБазы = Соединение.NewObject("Запрос");
// 2. Назначаем текст запроса через свойство Текст
ЗапросУдаленнойБазы.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Склад,
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.Характеристика,
| ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(,&Условия) КАК ТоварыНаСкладахОстатки
|ГДЕ
| ТоварыНаСкладахОстатки.Склад = &Склад
| И ТоварыНаСкладахОстатки.Номенклатура = &Номенклатура";
// 3. Получаем ссылки в контексте удаленной базы
НоменклатураУдаленнойБазы = Соединение.Справочники.Номенклатура.НайтиПоКоду(Объект.Номенклатура.Код);
СкладУдаленнойБазы = Соединение.Справочники.Склады.НайтиПоКоду(Объект.Склад.Код);
// 4. Устанавливаем параметры запроса
ЗапросУдаленнойБазы.УстановитьПараметр("Номенклатура", НоменклатураУдаленнойБазы);
ЗапросУдаленнойБазы.УстановитьПараметр("Склад", СкладУдаленнойБазы);
// 5. Выполняем запрос и выгружаем результат
Результат = ЗапросУдаленнойБазы.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка полученных строк
КонецЦикла;
Если код написан корректно, но платформа по-прежнему выдает ошибку «Метод объекта не обнаружен (NewObject)» или не видит свойства Текст, причиной может являться повреждение динамического кэша конфигурации или метаданных сеанса. Выполним следующие действия по очистке кэша:
%AppData%\1C\1Cv8 и %LocalAppData%\1C\1Cv8.12345678-abcd-1234-abcd-1234567890ab).Для предотвращения ошибок и снижения нагрузки на информационные системы важно соблюдать ключевые архитектурные правила:
СправочникСсылка) принадлежат контексту текущей базы. При передаче их в запрос внешней базы возникнет ошибка несоответствия типов. Необходимо передавать либо примитивные типы (числа, строки, даты), либо находить ссылки непосредственно через менеджеры удаленного COM-соединения.
ГУИД = Соединение.NewObject("УникальныйИдентификатор", Строка(Объект.Номенклатура.УникальныйИдентификатор()));
СсылкаВнешняя = Соединение.Справочники.Номенклатура.ПолучитьСсылку(ГУИД);
Соединение = Неопределено;. Это позволит вовремя освободить клиентскую лицензию 1С и завершить сеанс на удаленном сервере.