Как изменить свойства общего модуля в расширении и исправить ошибки при COM-соединении

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

При разработке расширений в системе 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью изменить свойства заимствованных объектов метаданных. Одной из самых острых проблем является попытка включить флаг Внешнее соединение для общего модуля, который в основной конфигурации доступен только на сервере. Это критично при интеграции систем через V83.COMConnector, когда стандартные подписки на события начинают выдавать ошибки. Рассмотрим подробнее, почему это происходит и как правильно решить задачу, используя возможности расширений.

Анализ проблемы: почему нельзя просто поставить галочку

Разберем ситуацию: в основной конфигурации существует общий модуль, в котором описаны обработчики подписок на события (например, ПередЗаписью). В свойствах модуля стоит только флаг Сервер. При попытке подключиться к базе через COM-соединение и записать объект, система выдает ошибку: Попытка передачи с клиента на сервер мутабельного значения. Это происходит потому, что контекст внешнего соединения платформа воспринимает как специфический вид клиента, и если модуль не помечен флагом Внешнее соединение, он недоступен напрямую. Платформа пытается передать объект (мутабельное значение) в серверный контекст, что запрещено.

Проанализируем поведение расширения. Когда мы заимствуем общий модуль в расширение, мы видим в палитре свойств флажки с синими и красными значками. Красный флажок означает, что свойство контролируется платформой и его изменение в расширении недопустимо, так как это нарушит логику компиляции модулей, определенную в основной конфигурации. Если попытаться принудительно отключить проверку в расширении, оно может просто перестать применяться в нужных контекстах.

Способ 1: Использование директив препроцессора и &ИзменениеИКонтроль

Выясним причину ошибки: часто нам вовсе не нужно, чтобы код подписки выполнялся именно при COM-соединении. Если логика подписки (например, открытие формы или работа с интерактивными объектами) не предназначена для внешних систем, самым правильным решением будет исключить выполнение этого кода. Рассмотрим, как это сделать без изменения основной конфигурации.

Посмотрим на пример реализации через механизм расширения:

  1. Заимствуем в расширение процедуру общего модуля, которая вызывает ошибку.
  2. Используем аннотацию &ИзменениеИКонтроль.
  3. Оборачиваем проблемный участок кода в директиву препроцессора #Если НЕ ВнешнееСоединение Тогда.

&ИзменениеИКонтроль("ДоговорКонтрагентаПередЗаписью")
Процедура ДоговорКонтрагентаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения)
    
    // #Вставка
    #Если НЕ ВнешнееСоединение Тогда
    // #КонецВставки
    
    // Здесь находится оригинальный код, который вызывает ошибку при COM-подключении
    // Например, попытка вызвать серверный метод с передачей источника (объекта)
    ПроверитьЗаполнениеРеквизитов(Источник);
    
    // #Вставка
    #КонецЕсли
    // #КонецВставки
    
КонецПроцедуры

Данный метод позволяет сохранить работоспособность системы при обычном использовании (на сервере или клиенте) и полностью игнорировать «опасный» код при подключении через внешнее соединение. Это устраняет причину возникновения ошибки мутабельного значения.

Способ 2: Создание модуля-дублера в расширении

Если же логика во внешнем соединении нам все-таки необходима, мы не можем просто отключить код. В этом случае проанализируем архитектурный обходной путь. Поскольку мы не можем менять свойства заимствованного модуля, мы можем создать новый общий модуль непосредственно в самом расширении.

Рассмотрим алгоритм действий:

  1. Создаем в расширении новый общий модуль, например, Расш_ОбщийМодульВнешнееСоединение.
  2. В свойствах этого модуля устанавливаем все необходимые флаги: Сервер, Внешнее соединение.
  3. В заимствованной процедуре основного модуля (через &Вместо или &После) вызываем методы из нашего нового модуля.

Так как наш новый модуль расширения изначально скомпилирован с флагом Внешнее соединение, платформа позволит вызывать его методы без передачи мутабельных значений через границы контекстов, которые она не может преодолеть в стандартном модуле.

Важные замечания по режиму совместимости

Проанализируем технические нюансы, упомянутые в обсуждении. При работе с расширениями в версии 8.3.14 крайне важно, чтобы Режим совместимости расширения полностью совпадал с режимом совместимости основной конфигурации. Если в расширении режим ниже, многие механизмы (включая работу с контекстами модулей) могут вести себя непредсказуемо.

Также стоит помнить: если платформа выдает сообщение «Значение контролируемого свойства ВнешнееСоединение не совпадает», нажатие кнопки «Исправить» в окне проверки возможности применения просто отключает контроль свойства в расширении. Это не меняет фактическое поведение скомпилированного кода в режиме предприятия, если свойство является жестко контролируемым. Поэтому наиболее надежным методом остается использование &ИзменениеИКонтроль или перенос логики в новые объекты расширения.

Резюме

Подведем итоги. Если вам нужно «включить» флаг общего модуля в расширении для работы по COM:

Использование этих подходов позволит избежать внесения изменений в основную конфигурацию, сохраняя её на поддержке, и обеспечит стабильную работу внешних интеграций.

← На главную