При организации интеграции между различными конфигурациями «1С:Предприятие» разработчики часто прибегают к использованию технологии COM-соединения (V83.COMConnector). Это достаточно простой способ напрямую подключиться к другой базе данных и программно создать в ней необходимые объекты, например, документы или справочники.
Однако при обновлении целевой конфигурации (особенно крупных систем, таких как «1С:ERP Управление предприятием» или «1С:КА») привычный обмен может внезапно прерваться критической ошибкой компиляции. Типичный пример такой ошибки:
{Документ.м29.Форма.ФормаДокумента.Форма(264)}: Ошибка при вызове метода контекста (СоздатьДокумент)
НовДок = СоединениеБУХ.Документы.ВнутреннееПотреблениеТоваров.СоздатьДокумент;
по причине:
Произошла исключительная ситуация (1C:Enterprise 8.3.12.1714):
Ошибка инициализации модуля: ОбщийМодуль.УСОERP_МодификацияКонфигурации.Модуль
{ОбщийМодуль.УСОERP_МодификацияКонфигурации.Модуль(3875,21)}: Процедура или функция с указанным именем не определена (ПолучитьСтруктуруОплаты)
В этой статье мы подробно разберем, почему возникает данная проблема, как устроена компиляция модулей в контексте внешнего соединения и как оперативно устранить эту ошибку несколькими способами.
Для того чтобы понять природу ошибки, рассмотрим механизм работы платформы «1С:Предприятие» при COM-подключении. Когда внешнее приложение выполняет вызов V83COMConnector.Connect() и пытается обратиться к метаданным (например, создать документ ВнутреннееПотреблениеТоваров), платформа инициализирует сеанс типа Внешнее соединение.
В этот момент происходит компиляция всех программных модулей, которые могут быть задействованы в работе данного сеанса. К ним относятся:
Проанализируем цепочку событий, приводящую к ошибке:
УСОERP_МодификацияКонфигурации имеет установленный флаг «Внешнее соединение» в своих свойствах. Следовательно, платформа обязана полностью скомпилировать его код при инициализации COM-сессии.ПолучитьСтруктуруОплаты().ПолучитьСтруктуруОплаты() расположена в другом общем модуле (например, в клиентском модуле УСОERP_МодификацияКонфигурацииКлиент), у которого флаг «Внешнее соединение» снят. И это абсолютно логично с точки зрения типовой архитектуры: на клиенте могут выполняться интерактивные методы (открытие форм, предупреждения), недопустимые во внешнем соединении.ПолучитьСтруктуруОплаты() становится «невидимой» для компилятора. Платформа прерывает компиляцию всего модуля УСОERP_МодификацияКонфигурации с ошибкой, что делает невозможным создание документа в коде интеграции.При этом, если запустить базу ERP в обычном режиме (тонкий или толстый клиент) и выполнить аналогичный код через внешнюю обработку, никакой ошибки не возникнет, так как в обычном сеансе клиентские модули успешно компилируются и доступны для вызова.
---
Прежде чем вносить изменения в код, нам необходимо локализовать все проблемные участки. Для этого воспользуемся встроенным инструментом синтаксического контроля платформы.
Выполним следующие действия по шагам:
После проверки в окне «Служебные сообщения» мы увидим точный список всех процедур, функций и модулей, которые вызывают ошибки компиляции именно в контексте внешнего соединения. Это убережет нас от ситуации, когда после исправления одной строчки обмен упадет на следующей.
---
В зависимости от того, имеем ли мы возможность изменять конфигурацию ERP напрямую (находится ли она на поддержке с возможностью редактирования) или конфигурация закрыта для изменений, мы можем применить один из трех подходов.
Если функция ПолучитьСтруктуруОплаты() отвечает за интерактивные действия (например, заполнение реквизитов формы на клиенте или вывод вопросов пользователю) и ее выполнение совершенно не требуется при автоматической загрузке документов по COM, мы можем просто исключить ее вызов из компиляции во внешнем соединении.
Для этого обернем вызов проблемной функции в директиву препроцессора:
#Если Не ВнешнееСоединение Тогда
// Данный код будет компилироваться и выполняться на клиенте и сервере,
// но полностью проигнорируется при подключении через COM-соединение
ПолучитьСтруктуруОплаты(ПараметрыДокумента);
#КонецЕсли
Этот способ является наиболее простым и безопасным, так как он гарантирует работоспособность механизма в интерактивном режиме и полностью решает проблему компиляции во внешнем соединении.
Если алгоритм функции ПолучитьСтруктуруОплаты() критически важен для корректного заполнения документа (например, рассчитывает графики платежей или заполняет важные реквизиты шапки), исключать его вызов нельзя.
В этом случае логику функции необходимо перенести из клиентского модуля в серверный общий модуль, у которого в свойствах взведены флаги «Сервер» и «Внешнее соединение». После этого вызов функции в модуле УСОERP_МодификацияКонфигурации переадресуется на новый серверный модуль.
Если типовая конфигурация ERP находится на строгой поддержке и напрямую вносить изменения в нее нельзя, мы можем использовать механизм расширений. Это современный и безопасный способ модификации логики без снятия конфигурации с поддержки.
Выполним исправление по шагам:
УСОERP_МодификацияКонфигурации.ПолучитьСтруктуруОплаты(). Предположим, этот метод называется ПередЗаписьюДокумента.&Вместо:
&Вместо("ПередЗаписьюДокумента")
Процедура Расш_ПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения)
// Если обмен идет через COM-соединение, мы обходим вызов проблемных клиентских методов
#Если ВнешнееСоединение Тогда
// Здесь мы пишем альтернативную логику для COM, которая заменяет вызов ПолучитьСтруктуруОплаты
// или просто игнорируем этот вызов, если он не критичен
#Иначе
// В обычном режиме вызываем стандартный метод конфигурации
ПродолжитьВызов(Источник, Отказ, РежимЗаписи, РежимПроведения);
#КонецЕсли
КонецПроцедуры
Важное примечание: Обязательно проверьте свойства самого расширения в дереве объектов. У него также должны быть правильно настроены свойства поддержки контекстов (клиент/сервер/внешнее соединение).
---
Рассмотренная нами ошибка — это лишь следствие более глубокой архитектурной проблемы. Использование технологии V83.COMConnector для интеграции крупных ERP-систем в современных реалиях накладывает на проект высокие риски и технические ограничения.
Рассмотрим подробнее ключевые недостатки COM-соединений:
comcntr.dll через службы компонентов COM+ часто превращаются в сложную техническую проблему.Для обеспечения стабильного обмена данными мы рекомендуем рассмотреть постепенный переход на современные способы интеграции:
Использование современных интеграционных механизмов сделает ваши системы независимыми от обновлений кода друг друга и гарантирует бесперебойную работу бизнес-процессов.