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