Интеграция между конфигурациями 1С с использованием механизма V83.COMConnector — частая практика при необходимости быстро получить данные из одной базы в другую. Однако при вызове экспортных процедур и функций разработчики нередко сталкиваются с исключением: «Ошибка при вызове метода контекста: Ошибка инициализации модуля. Переменная РежимДиалогаВопрос не определена». Разберем природу возникновения этой ошибки, выясним скрытые нюансы компиляции модулей во внешнем соединении и рассмотрим правильные варианты решения проблемы.
Проанализируем контекст исполнения кода. Внешнее подключение к базе 1С через COMConnector выполняется исключительно в невизуальном режиме. В таком сеансе полностью отсутствует интерфейсная часть: платформа не создает окна, диалоги и пользовательские формы. Системные перечисления и глобальные функции, предназначенные для взаимодействия с пользователем (такие как РежимДиалогаВопрос, Вопрос(), Предупреждение(), ОткрытьФорму()), в данном окружении просто не существуют.
Когда вызывающая база обращается к общему модулю во внешней информационной базе, платформа компилирует его код для контекста внешнего соединения. Если в теле модуля, в секции инициализации или в вызываемой цепочке процедур встречается обращение к переменным интерфейса без соответствующих директив компиляции, синтаксический анализатор платформы выдает критическую ошибку инициализации, прерывая выполнение операции.
Посмотрим на распространенную ошибку: попытку назначить общему модулю признак Глобальный, чтобы не указывать его имя при вызове метода. Рассмотрим, к чему это приводит:
Connect()), а не в момент непосредственного обращения к функции.Рекомендуется снять флаг Глобальный в свойствах модуля. В этом случае модуль компилируется «по требованию» — только тогда, когда к нему происходит прямое обращение через COM-объект:
БазаЗУП = Новый COMОбъект("V83.COMConnector");
Соединение = БазаЗУП.Connect(СтрокаСоединения);
// Явное обращение к общему модулю и его экспортной функции
Таблица = Соединение.ИнтеграцияПочтовик.ПолучитьОстатокОтпускаСпискаСотрудников();
Разберем основной способ устранения ошибки, если модуль должен одновременно использоваться и в интерактивном клиентском интерфейсе, и при интеграциях. Все участки кода, где присутствуют диалоги с пользователем, необходимо обрамить директивами условной компиляции.
Рассмотрим пример изоляции вызова интерактивного вопроса:
#Если Клиент И Не ВнешнееСоединение Тогда
Ответ = Вопрос("Выполнить операцию?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
#КонецЕсли
Обратите особое внимание на сигнатуры процедур и функций. Ошибку инициализации могут вызывать значения параметров по умолчанию, если в них указаны системные клиентские перечисления, например:
// ОШИБОЧНО: сигнатура компилируется целиком, модуль не инициализируется во внешнем соединении
Функция ЗапроситьПодтверждение(ТипВопроса = РежимДиалогаВопрос.ОК) Экспорт
// ПРАВИЛЬНО: значение по умолчанию устанавливается внутри тела метода с проверкой контекста
Функция ЗапроситьПодтверждение(ТипВопроса = Неопределено) Экспорт
#Если Не ВнешнееСоединение Тогда
Если ТипВопроса = Неопределено Тогда
ТипВопроса = РежимДиалогаВопрос.ОК;
КонецЕсли;
#КонецЕсли
КонецФункции
Проанализируем свойства общего модуля в дереве метаданных. Для модулей, обеспечивающих интеграционный программный интерфейс (API базы), рекомендуется следовать правилу разделения ответственности:
ИнтеграцияВнешнееСоединение).Чтобы не искать ошибки вслепую, запустим встроенный механизм проверки конфигурации:
Конфигуратор проверит все модули именно в том контексте, в котором работает COM-соединение, и выведет полный список строк, где используются недопустимые переменные или методы.
Иногда при вызове функции из базы ЗУП требуется получить данные из третьей системы (например, PostgreSQL). Попытка создать цепочку COM-соединений («COM в COM») технически возможна, но архитектурно нежелательна по следующим причинам:
dllhost.exe.ТаблицаЗначений) через COM приводит к тому, что каждая строка и колонка преобразуются во внутренние COM-объекты. Чтение такой таблицы вызывающей базой в циклах выполняется крайне медленно.Для надежной архитектуры рекомендуются более современные подходы: