Почему возникает ошибка «Метод объекта не обнаружен (ПолучитьСтруктуруХраненияБазыДанных)» при COM-соединении и как её исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции баз данных 1С и разработке инструментов мониторинга (например, в Центре управления производительностью — ЦУП) нередко требуется получить соответствие объектов конфигурации реальным таблицам в реляционной СУБД через внешнее соединение. Однако вызов глобальной функции ПолучитьСтруктуруХраненияБазыДанных у объекта COM-подключения может завершиться аварийно с ошибкой вида «Метод объекта не обнаружен (ПолучитьСтруктуруХраненияБазыДанных)».

Разберем детально, почему возникает данное исключение в COM-контексте, и рассмотрим проверенные способы устранения неполадки.

Причины возникновения ошибки

Проанализируем ключевые факторы, приводящие к сбою вызова функции через COMОбъект:

  1. Особенности диспетчеризации COM (IDispatch) и локализация: В ряде версий платформы диспетчер Automation нестабильно распознает русскоязычные имена глобальных системных функций и системных литералов (таких как Истина и Ложь). Это зависит от региональных настроек операционной системы, настроек пользователя сеанса COM и установленного языка интерфейса. В результате COM-объект не может сопоставить кириллическое имя метода с его внутренней реализацией.
  2. Ошибки инициализации модулей внешнего соединения: При первом подключении к информационной базе компилируются модули с признаком «Внешнее соединение». Если в коде конфигурации подключаемой базы присутствуют вызовы клиентских процедур без директив условной компиляции #Если Клиент Тогда, контекст инициализируется некорректно, что делает вызов методов недоступным.
  3. Разрядность и версии библиотеки comcntr.dll: Несовпадение разрядности клиентского приложения (32/64 бит) и сервера, а также рассинхронизация версий зарегистрированной компоненты внешнего соединения с текущей версией платформы 1С приводят к ошибкам маршалинга.

Способ 1. Использование англоязычного синтаксиса метода и параметров

Самым быстрым и простым решением при непосредственном вызове метода через COM является переход на международный (англоязычный) синтаксис платформы 1С. Метод ПолучитьСтруктуруХраненияБазыДанных в англоязычном варианте называется GetDBStorageStructureInfo.

Посмотрим на пример адаптации кода:


// Нестабильный вариант:
// ТаблицаСтруктуры = СоединениеИБ.ПолучитьСтруктуруХраненияБазыДанных(, Истина);

// Рабочий вариант с использованием англоязычного синтаксиса:
ТаблицаСтруктуры = СоединениеИБ.GetDBStorageStructureInfo(, true);

Обратите внимание на передачу булевого параметра: вместо русскоязычного литерала Истина при вызове COM-методов рекомендуется передавать системную константу true (или false соответственно). Это снимает проблему некорректной локализации в Automation-интерфейсе.

Способ 2. Обертка вызова в общем модуле подключаемой базы

Для создания отказоустойчивой интеграции наилучшей практикой является вынос вызова системного метода внутрь подключаемой базы. Рассмотрим, как это реализовать по шагам:

  1. В подключаемой информационной базе создаем или открываем общий модуль.
  2. В свойствах общего модуля устанавливаем флаги «Сервер» и «Внешнее соединение» (а также «Вызов сервера», если планируются клиентские вызовы).
  3. Объявляем экспортную функцию, которая выполняет вызов метода локально, где кириллический синтаксис поддерживается штатно:

// Код в общем модуле подключаемой базы (например, ИнтеграцияСлужебный)
Функция ПолучитьСтруктуруТаблиц(МассивИмен = Неопределено, ВключаяИндексы = Истина) Экспорт
    
    // Внутри базы метод выполняется в нативном контексте сервера
    ТаблицаХранения = ПолучитьСтруктуруХраненияБазыДанных(МассивИмен, ВключаяИндексы);
    
    // Для надежной передачи через COM преобразуем ТаблицуЗначений в массив структур
    МассивРезультат = Новый Массив;
    
    Для Каждого Стр Из ТаблицаХранения Цикл
        СтрДанных = Новый Структура;
        СтрДанных.Вставить("ИмяТаблицы", Стр.ИмяТаблицы);
        СтрДанных.Вставить("ИмяТаблицыХранения", Стр.ИмяТаблицыХранения);
        СтрДанных.Вставить("Назначение", Стр.Назначение);
        МассивРезультат.Добавить(СтрДанных);
    КонецЦикла;
    
    Возврат МассивРезультат;
    
КонецФункции

Теперь на стороне вызывающей базы достаточно обратиться к созданной экспортной функции:

СтруктураБД = СоединениеИБ.ИнтеграцияСлужебный.ПолучитьСтруктуруТаблиц();

Особенности передачи параметров и обработки результата через COM

При взаимодействии через COM-соединение важно учитывать следующие системные ограничения:

  1. Передача объектов первого параметра: Если требуется получить структуру не для всей конфигурации, а для списка объектов, нельзя передавать массив, созданный в текущей базе. Массив должен быть создан в контексте внешнего соединения:
    
    МассивОбъектов = СоединениеИБ.NewObject("Array");
    МассивОбъектов.Add("Справочник.Номенклатура");
    Результат = СоединениеИБ.GetDBStorageStructureInfo(МассивОбъектов, true);
    
  2. Маршалинг ТаблицыЗначений: При возврате стандартной таблицы значений из COM-сеанса обход через цикл Для Каждого может вызывать исключения. Надежнее обращаться к строкам по индексу (от 0 до Количество() - 1) через метод Получить(Индекс) либо передавать сериализованные данные (JSON, Массив структур).
← На главную