При интеграции баз данных 1С и разработке инструментов мониторинга (например, в Центре управления производительностью — ЦУП) нередко требуется получить соответствие объектов конфигурации реальным таблицам в реляционной СУБД через внешнее соединение. Однако вызов глобальной функции ПолучитьСтруктуруХраненияБазыДанных у объекта COM-подключения может завершиться аварийно с ошибкой вида «Метод объекта не обнаружен (ПолучитьСтруктуруХраненияБазыДанных)».
Разберем детально, почему возникает данное исключение в COM-контексте, и рассмотрим проверенные способы устранения неполадки.
Проанализируем ключевые факторы, приводящие к сбою вызова функции через COMОбъект:
Истина и Ложь). Это зависит от региональных настроек операционной системы, настроек пользователя сеанса COM и установленного языка интерфейса. В результате COM-объект не может сопоставить кириллическое имя метода с его внутренней реализацией.#Если Клиент Тогда, контекст инициализируется некорректно, что делает вызов методов недоступным.comcntr.dll: Несовпадение разрядности клиентского приложения (32/64 бит) и сервера, а также рассинхронизация версий зарегистрированной компоненты внешнего соединения с текущей версией платформы 1С приводят к ошибкам маршалинга.Самым быстрым и простым решением при непосредственном вызове метода через COM является переход на международный (англоязычный) синтаксис платформы 1С. Метод ПолучитьСтруктуруХраненияБазыДанных в англоязычном варианте называется GetDBStorageStructureInfo.
Посмотрим на пример адаптации кода:
// Нестабильный вариант:
// ТаблицаСтруктуры = СоединениеИБ.ПолучитьСтруктуруХраненияБазыДанных(, Истина);
// Рабочий вариант с использованием англоязычного синтаксиса:
ТаблицаСтруктуры = СоединениеИБ.GetDBStorageStructureInfo(, true);
Обратите внимание на передачу булевого параметра: вместо русскоязычного литерала Истина при вызове COM-методов рекомендуется передавать системную константу true (или false соответственно). Это снимает проблему некорректной локализации в Automation-интерфейсе.
Для создания отказоустойчивой интеграции наилучшей практикой является вынос вызова системного метода внутрь подключаемой базы. Рассмотрим, как это реализовать по шагам:
// Код в общем модуле подключаемой базы (например, ИнтеграцияСлужебный)
Функция ПолучитьСтруктуруТаблиц(МассивИмен = Неопределено, ВключаяИндексы = Истина) Экспорт
// Внутри базы метод выполняется в нативном контексте сервера
ТаблицаХранения = ПолучитьСтруктуруХраненияБазыДанных(МассивИмен, ВключаяИндексы);
// Для надежной передачи через COM преобразуем ТаблицуЗначений в массив структур
МассивРезультат = Новый Массив;
Для Каждого Стр Из ТаблицаХранения Цикл
СтрДанных = Новый Структура;
СтрДанных.Вставить("ИмяТаблицы", Стр.ИмяТаблицы);
СтрДанных.Вставить("ИмяТаблицыХранения", Стр.ИмяТаблицыХранения);
СтрДанных.Вставить("Назначение", Стр.Назначение);
МассивРезультат.Добавить(СтрДанных);
КонецЦикла;
Возврат МассивРезультат;
КонецФункции
Теперь на стороне вызывающей базы достаточно обратиться к созданной экспортной функции:
СтруктураБД = СоединениеИБ.ИнтеграцияСлужебный.ПолучитьСтруктуруТаблиц();
При взаимодействии через COM-соединение важно учитывать следующие системные ограничения:
МассивОбъектов = СоединениеИБ.NewObject("Array");
МассивОбъектов.Add("Справочник.Номенклатура");
Результат = СоединениеИБ.GetDBStorageStructureInfo(МассивОбъектов, true);
Для Каждого может вызывать исключения. Надежнее обращаться к строкам по индексу (от 0 до Количество() - 1) через метод Получить(Индекс) либо передавать сериализованные данные (JSON, Массив структур).