Работа с технологией COM в среде 1С:Предприятие часто сопровождается трудностями в обеспечении «видимости» процедур и функций. Одной из самых распространенных ошибок является исключение, при котором система сообщает: «Метод объекта не обнаружен», хотя в конфигураторе процедура явно присутствует. В рамках данной статьи мы подробно разберем, почему возникает эта ситуация, проанализируем типичные ошибки разработчиков и найдем пути их решения, используя в том числе инструментарий для анализа конфигураций на наличие ошибок в вызовах экспортных процедур.
Рассмотрим типичный сценарий: программист пытается вызвать процедуру из общего модуля удаленной информационной базы через объект COMConnector. Код инициализации и вызова может выглядеть следующим образом:
Описание = Новый Структура;
Описание.Вставить("Имя", "Подсистема1");
Описание.Вставить("Версия", "1.0");
// Создаем структуру в контексте удаленной базы
УдаленноеОписание = ПодключениеКБазе.NewObject("Структура");
Для Каждого КлючЗначение Из Описание Цикл
УдаленноеОписание.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
КонецЦикла;
// Вызов метода общего модуля
Результат = ПодключениеКБазе.ЛицензированиеСлужебный.ПриДобавленииПодсистемы(УдаленноеОписание);
Несмотря на то, что объект ПодключениеКБазе успешно создан, а модуль ЛицензированиеСлужебный существует, вызов завершается ошибкой. Чтобы быстро выявить подобные несоответствия в проекте, рекомендуется использовать статический анализатор кода, который проверяет конфигурации и расширения на корректность обращений.
Первое, на что необходимо обратить внимание, — это свойства общего модуля в дереве конфигурации. Для того чтобы метод был доступен через COM-соединение, должны быть соблюдены два условия:
Экспорт.Важно помнить, что если вы работаете с расширениями конфигурации, эти же флаги должны быть установлены и в свойствах модуля внутри расширения.
Выясним критическую разницу между двумя подходами к управлению кодом. Часто разработчики по привычке используют директивы &НаСервере или &НаКлиенте в общих модулях, особенно если они были скопированы из модулей форм. Рассмотрим, как это влияет на работу:
Директивы компиляции (начинаются с символа &) предназначены для управления контекстом в модулях форм и команд. В общих модулях они могут игнорироваться или приводить к тому, что метод становится невидимым для внешнего подключения.
Правильным подходом для обеспечения доступности кода во внешнем соединении является использование инструкций препроцессора (начинаются с символа #). Посмотрим на пример кода, который гарантированно работает:
#Если Сервер Или ВнешнееСоединение Тогда
Процедура ПриДобавленииПодсистемы(Описание) Экспорт
// Логика работы процедуры
Сообщить("Метод вызван успешно");
КонецПроцедуры
#КонецЕсли
В данном случае мы явно указываем компилятору, что этот блок кода должен быть включен в сборку как для серверного контекста, так и для контекста внешнего соединения (COM). Если ваша процедура была обернута только в #Если Сервер, то при подключении через V83.COMConnector она может быть недоступна.
Проанализируем еще один важный нюанс, который косвенно может приводить к ошибкам поиска метода. При вызове ПодключениеКБазе.ИмяМодуля.ИмяПроцедуры(Параметр), передаваемый Параметр должен быть «понятен» принимающей стороне.
Если вы передадите обычную Структура, созданную в текущей базе, в метод удаленной базы, система может выдать ошибку. Это происходит потому, что объект одного процесса не может быть напрямую обработан другим. В качестве альтернативного способа интеграции систем можно также рассмотреть использование COM-объектов на Python для 1С.
Правильное решение при работе через стандартный COM-коннектор — создавать объект в контексте той базы, к которой вы подключаетесь, как это показано в примере автора:
// Правильное создание объекта для передачи в COM
УдаленнаяСтруктура = ПодключениеКБазе.NewObject("Структура");
Если вы попытаетесь вызвать метод и передадите ему «родную» структуру текущей базы, 1С иногда может не найти подходящую сигнатуру метода и выдать неинформативное сообщение о том, что метод не найден.
Иногда причина кроется в банальном кэшировании. Если вы только что добавили флаг Внешнее соединение или слово Экспорт, сервер 1С может хранить старую версию скомпилированного модуля. Для решения этой проблемы рекомендуется:
Подведем итог нашему исследованию. Для успешного вызова метода через COM-соединение выполните следующий чек-лист:
Экспорт у вызываемой процедуры.&НаСервере на инструкции препроцессора #Если Сервер Или ВнешнееСоединение Тогда.Подключение.NewObject().Соблюдение этих правил позволит вам избежать большинства ошибок, связанных с контекстной видимостью кода при интеграции различных информационных систем на базе 1С.