К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как обратиться к общему модулю из расширения 1С

Как вызвать процедуры и функции общего модуля основной конфигурации из расширения 1С, какие ограничения есть у аннотации &Вместо и как правильно организовать код.

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

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

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

Как устроена видимость объектов между расширением и конфигурацией

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

Обратное направление закрыто: общий модуль, созданный в расширении, нельзя вызвать из модулей основной конфигурации. Это осознанное ограничение платформы — поставщик конфигурации не должен зависеть от кода, которого может не быть в конкретной информационной базе.

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

Вызов общего модуля конфигурации из кода расширения

Самый простой сценарий — прямой вызов экспортной процедуры или функции общего модуля основной конфигурации. Для этого модуль даже не нужно заимствовать в расширение: достаточно, чтобы он существовал в конфигурации, а нужный метод был объявлен с ключевым словом «Экспорт».

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

// Вызов общего модуля основной конфигурации

ТекущийПользователь = Пользователи.ТекущийПользователь();

ОбщегоНазначения.СообщитьПользователю("Расширение инициализировано");

КонецПроцедуры

Обращение выполняется по имени модуля точно так же, как в коде самой конфигурации: ИмяМодуля.ИмяМетода(Параметры). Контекст вызова сохраняется: серверный общий модуль нельзя вызвать из клиентской процедуры без директивы &НаСервере или серверного вызова.

Если модуль конфигурации не экспортирует нужный метод (нет ключевого слова «Экспорт»), обратиться к нему снаружи невозможно. В этом случае придётся искать публичный программный интерфейс — многие типовые конфигурации выносят доступные методы в модули с постфиксами «ВызовСервера», «Клиент», «Переопределяемый».

Создание собственного общего модуля в расширении

Часто удобнее не разбрасывать логику по формам и модулям объектов, а создать собственный общий модуль прямо в расширении. Для этого в конфигураторе откройте расширение, в ветке «Общие» → «Общие модули» добавьте новый модуль и задайте его свойства.

Свойства настраиваются так же, как у обычного общего модуля: флаги «Сервер», «Клиент», «Вызов сервера», «Привилегированный режим». Рекомендуемый минимум для модуля с бизнес-логикой — «Сервер» и «Вызов сервера», чтобы его можно было вызывать с клиента.

Вызов собственного модуля из кода расширения выполняется по имени, без каких-либо префиксов:

&НаКлиенте

Процедура ОбработатьДокумент(Команда)

Результат = Расш1_ОбработкаДокументов.ПроверитьЗаполнение(Объект.Ссылка);

Если Не Результат.Успешно Тогда

ПоказатьПредупреждение(, Результат.ТекстОшибки);

КонецЕсли;

КонецПроцедуры

Хорошая практика — добавлять к имени модуля префикс расширения (например, «Расш1_»). Это исключает коллизию имён, если поставщик в новой версии добавит общий модуль с таким же именем: при совпадении имён расширение может перестать применяться.

Порядок создания общего модуля в расширении
  1. 1
    Откройте конфигуратор, загрузите расширение через «Конфигурация → Расширения конфигурации»
  2. 2
    В дереве расширения раскройте «Общие», нажмите «Добавить» на ветке «Общие модули»
  3. 3
    Задайте имя с префиксом расширения, отметьте свойства «Сервер» и «Вызов сервера»
  4. 4
    Напишите экспортные процедуры и функции с ключевым словом «Экспорт»
  5. 5
    Обновите конфигурацию базы данных и проверьте вызов из формы расширения

Заимствование общего модуля и аннотации изменения

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

Доступны три аннотации. &Перед и &После добавляют код до или после типового метода. &Вместо полностью заменяет метод, при этом типовой код можно вызвать внутри через специальную конструкцию ПродолжитьВызов().

&Вместо("РассчитатьСкидку")

Функция Расш1_РассчитатьСкидку(ПараметрыДокумента)

Если ПараметрыДокумента.ЭтоОсобыйКлиент Тогда

Возврат 15; // собственная логика

КонецЕсли;

Возврат ПродолжитьВызов(ПараметрыДокумента); // типовая логика

КонецФункции

Аннотация &ИзменениеИКонтроль позволяет вставить собственные фрагменты внутрь текста типового метода с минимальной связанностью. Это предпочтительный способ для сложных типовых процедур: при обновлении конфигурации платформа сможет сопоставить изменённые участки с новым кодом поставщика.

Типичные ошибки
01
Использование &Вместо без вызова ПродолжитьВызов — типовая логика теряется полностью, а после обновления конфигурации расширение отключается из-за несовпадения текста метода
02
Заимствование всего модуля ради одного метода — растёт объём контроля при обновлении, заимствуйте только нужные методы
03
Обращение к неэкспортным методам модуля — код не компилируется, нужно искать публичный интерфейс
04
Имя собственного модуля без префикса — при появлении одноимённого модуля у поставщика расширение перестаёт применяться

Ограничения и особенности серверных вызовов

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

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

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

Проверка расширения после обновления конфигурации

Главный риск при обращении к общим модулям конфигурации — их изменение поставщиком. После обновления конфигурации откройте список расширений («Все функции → Стандартные → Управление расширениями конфигурации» или соответствующий раздел администрирования) и убедитесь, что расширение подключено и не помечено как неприменимое.

В конфигураторе выполните проверку расширения: «Конфигурация → Проверка конфигурации» с выбранным расширением. Ошибки вида «Процедура или функция с указанным именем не определена» означают, что вызываемый метод общего модуля переименован или удалён — нужно найти его аналог в новой версии и скорректировать вызов.

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

Контрольные точки

Как проверить результат

Статус расширения в списке
Норма

Подключено, без пометок о неприменимости

Тревожный признак

Снят флажок или есть предупреждение о несовместимости

Проверка конфигурации в конфигураторе
Норма

Ошибок по модулям расширения нет

Тревожный признак

Ошибки «метод не определён» по вызовам общих модулей

Выполнение сценария в пользовательском режиме
Норма

Код расширения отрабатывает, типовая логика сохранена

Тревожный признак

Ошибка вызова или исчезновение типового поведения

Альтернативы прямому обращению к общим модулям

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

Для обмена данными между своими доработками используйте собственные общие модули расширения, а для точек расширения типовой логики — переопределяемые модули поставщика (с постфиксом «Переопределяемый»). Типовые конфигурации специально выносят в них методы, предназначенные для доработки, — такие вызовы стабильнее при обновлениях.

Маршрут решения

Как выбрать подход

Нужно просто вызвать типовую функцию из кода расширенияВызывайте общий модуль конфигурации напрямую по имени, без заимствования
Нужно изменить поведение типового методаЗаимствуйте модуль и используйте &ИзменениеИКонтроль или &Вместо с ПродолжитьВызов
Нужна собственная бизнес-логикаСоздайте общий модуль в расширении с префиксом в имени
Есть переопределяемый модуль поставщика под вашу задачуИспользуйте его — это самый устойчивый к обновлениям вариант

Часто задаваемые вопросы

Можно ли из расширения вызвать общий модуль другого расширения?

Нет, расширения изолированы друг от друга. Каждое расширение видит только основную конфигурацию и собственные объекты. Если двум расширениям нужна общая логика, её придётся продублировать в каждом или вынести во внешнюю обработку.

Почему вызов общего модуля из расширения даёт ошибку «Метод не обнаружен»?

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

Нужно ли заимствовать общий модуль, чтобы просто вызвать его метод?

Нет. Заимствование требуется только для изменения поведения методов. Для обычного вызова достаточно обратиться к модулю по имени из любого кода расширения.

Что произойдёт, если поставщик добавит модуль с именем моего модуля расширения?

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

Можно ли в расширении обратиться к модулю менеджера или модулю объекта?

Да, через менеджер объекта: например, Справочники.Номенклатура.ИмяМетода() для модуля менеджера. Модуль объекта доступен только через сам объект после получения его ссылки методом ПолучитьОбъект(). Ограничения те же — метод должен быть экспортным.

Как отладить код общего модуля, вызываемого из расширения?

Точки останова ставятся в конфигураторе как обычно — и в заимствованных модулях, и в собственных модулях расширения. Отладка работает прозрачно: при входе в вызов типового модуля откроется его текст. Убедитесь, что отладка разрешена на сервере и расширение подключено в отлаживаемом сеансе.

Итог

Что важно запомнить

Из расширения общие модули конфигурации вызываются напрямую по имени, заимствование нужно только для изменения методов. Собственные модули создавайте в расширении с уникальным префиксом. Минимизируйте аннотации &Вместо и проверяйте расширение после каждого обновления конфигурации — это главная защита от отказа доработки.