Свой код в модуле объекта через расширение конфигурации 1С

· 9 мин

Содержание

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

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

Чем модуль расширения отличается от обычного модуля

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

Для объекта в расширении есть два состояния:

  • 🔗 заимствованный объект — копия структуры объекта из основной конфигурации. Реквизиты и формы видны, но менять их состав нельзя, только расширять;
  • 🆕 собственный объект — создан в расширении с нуля. Его можно менять как угодно, но основная конфигурация о нём не знает, пока вы не подключите его кодом.

Модуль объекта у заимствованного объекта изначально пуст. В нём нет копии кода оригинала. Вы пишете только то, что должно сработать дополнительно или вместо штатного поведения.

Расширение не копирует исходный код типовой конфигурации. Поэтому вашу правку легко увидеть: в модуле только ваши строки, ничего лишнего.

Какие модули бывают у объекта:

МодульЧто в нём обычно пишутЧто можно перехватить
Модуль объектаПроведение, запись, заполнение, проверка перед записьюПроцедуры-обработчики объекта и его собственные экспортные методы
Модуль менеджераМетоды справочника или документа в целом, обработчики получения данных выбораЭкспортные процедуры и функции менеджера
Модуль формыРеакция на кнопки, события формы и её элементовОбработчики и процедуры формы
Модуль набора записей (у регистров)Контроль записи набораОбработчики набора записей

Подготовка: расширение и заимствованный объект

Сначала нужно само расширение. Если оно уже есть в базе, этот шаг пропустите.

  1. Откройте базу в Конфигураторе. Используйте тестовую копию, а не рабочую базу.
  2. В главном меню выберите Конфигурация и пункт про расширения конфигурации . Откроется список расширений.
  3. Нажмите «Добавить», задайте имя и префикс. Префикс из пары-тройки букв (например, Мк_) пригодится позже: он отличает ваши процедуры от типовых и защищает от совпадения имён.
  4. Сохраните расширение и обновите конфигурацию базы данных.

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

Дальше заимствуем объект:

  1. Откройте конфигурацию расширения. Если в окне дерева её не видно, выберите пункт Конфигурация → Расширения конфигурации и откройте нужное через контекстное меню.
  2. В дереве расширения вызовите контекстное меню на ветке нужного вида объектов (например, «Документы») и выберите добавление объектов основной конфигурации.
  3. В открывшемся окне отметьте нужный документ или справочник. Платформа предупредит, что вместе с ним могут заимствоваться связанные объекты: типы, на которые он ссылается, подсистемы. Это нормально.
  4. Подтвердите. Объект появится в дереве расширения с пометкой «заимствован».

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

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

Как писать код: аннотации &Перед, &После, &Вместо

Главный инструмент расширения — аннотации перед процедурой. Они говорят платформе, как встроить вашу процедуру в существующую. Имя процедуры должно совпадать с именем перехватываемой процедуры оригинала, а аннотация указывает режим.

Например, нужно проверить поле перед проведением документа:

&Перед("ПередЗаписью")
Процедура Мк_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если ПустаяСтрока(Комментарий) Тогда
        ТекстСообщения = "Заполните комментарий к документу";
        Сообщить(ТекстСообщения);
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

Строка &Перед("ПередЗаписью") связывает вашу процедуру со штатным обработчиком. Имя вашей процедуры может отличаться: его определяет аннотация, но префикс делает код читаемым.

Четыре режима:

  • ⬆️ &Перед — ваш код выполнится до штатного. Безопасный вариант по умолчанию;
  • ⬇️ &После — выполнится после штатного. Удобно для дополнительных действий, когда результат оригинала уже известен;
  • 🔁 &Вместо — оригинал не вызывается сам. Вы решаете, вызывать ли его, через специальный оператор ПродолжитьВызов;
  • ✏️ &ИзменениеИКонтроль — платформа копирует тело оригинала в ваш модуль, и вы вставляете свои блоки с маркерами #Вставка и #Удаление. Это самый хрупкий способ.

Порядок выбора такой: сначала &Перед или &После, потом &Вместо, а &ИзменениеИКонтроль оставьте на крайний случай. Чем меньше вы вмешиваетесь, тем реже ломаются обновления.

Если нужен вызов оригинала

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

&Вместо("ОбработкаПроведения")
Процедура Мк_ОбработкаПроведения(Отказ, РежимПроведения)
    // подготовка данных
    ПродолжитьВызов(Отказ, РежимПроведения);
    // дополнительные действия после типового проведения
КонецПроцедуры

Если в процедуре с &Вместо забыть ПродолжитьВызов, типовое поведение просто пропадёт. Документ перестанет делать проводки, и заметят это не сразу, а при закрытии периода.

Свой метод вместо перехвата

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

Модуль формы: события интерфейса и элементы

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

Что важно в формах:

  1. Событие формы (например, при открытии или при создании на сервере) перехватывается теми же аннотациями, что и в модуле объекта.
  2. Новый реквизит формы, который вы добавили сами, живёт только в расширении. Он будет доступен в ваших процедурах и в типовой форме тоже.
  3. Новую кнопку или поле можно добавить в расширении. Для этого в редакторе формы расширения перетаскивайте элементы как обычно.
  4. Для обработчиков действий над элементами нужны директивы компиляции: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста. Без директивы вызов клиентской процедуры с сервера не сработает.

Пример: после открытия формы показать подсказку.

&После("ПриОткрытии")
&НаКлиенте
Процедура Мк_ПриОткрытии(Отказ)
    // действие после штатного открытия формы
КонецПроцедуры

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

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

Подписки на события: логика на уровне всей конфигурации

Иногда один и тот же код нужен для многих объектов: например, записывать в журнал каждое изменение документов нескольких видов. Писать то же самое в каждом модуле объекта неудобно. Для этого есть подписки на события.

Как это устроено:

  1. В расширении создайте собственный общий модуль, где будет лежать процедура-обработчик.
  2. Создайте объект «Подписка на событие». Укажите событие (например, перед записью), источники — нужные документы или справочники — и процедуру общего модуля.
  3. В общем модуле опишите процедуру с параметрами Источник и Отказ. Для событий записи и проведения набор параметров определяется платформой.

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

Когда что использовать:

ЗадачаЧто лучше
Проверка в одном документеАннотация &Перед в модуле объекта
Одинаковое действие для многих типов объектовПодписка на событие
Изменение поведения формыМодуль формы расширения
Новая общая функция для нескольких местОбщий модуль расширения
Подмена штатной логики целиком&Вместо, но осторожно
Куда поместить новый код в расширении?

Свойства расширения и безопасность

Перед тем как включать расширение в рабочую базу, посмотрите свойства. Они влияют на то, что платформа вообще разрешит расширению делать.

  • 🔒 Безопасный режим — ограничивает операции расширения с внешними ресурсами, файлами и COM. По умолчанию его включают для расширений, пришедших извне;
  • 🛡️ Защита от опасных действий — при включении платформа спрашивает пользователя перед запуском расширения с потенциально опасным кодом;
  • 🎯 Область действия — расширение можно подключить ко всей базе, а можно ограничить отдельными пользователями или ролями (в зависимости от версии платформы набор вариантов может различаться).

Если вы пишете расширение сами, безопасный режим можно отключить в тестовой базе. Для расширения, которое вы получили извне, отключайте режим только после проверки кода.

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

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

Порядок проверки:

  1. Откройте тестовую базу в режиме 1С:Предприятия и повторите действие, которое должно вызывать ваш код: создайте документ, запишите, проведите.
  2. Если код не сработал, поставьте точку останова в модуле расширения (клавиша F9) и запустите отладку (F5).
  3. Остановка на точке означает, что расширение подключено и перехват работает. Если остановки нет, проверьте, что расширение активно и что имя события в аннотации написано точно.
  4. Пройдите отладку по шагам (F11) и сравните значения параметров с ожидаемыми.

Для отладки нужен режим запуска из Конфигуратора. Тонкий клиент отладка тоже поддерживает, но настройки отладки в этом случае задаются отдельно. Если останов не случается, проверьте в Конфигураторе настройки отладки (меню Сервис → Параметры → Запуск 1С:Предприятия).

Перед передачей расширения в рабочую базу
Выполнено: 0 / 7

Частые ошибки

Самое частое: разработчик создаёт модуль, пишет код и не видит эффекта. Причины обычно одни и те же.

  • ❌ Опечатка в имени события в аннотации. Платформа может не выдать ошибку при проверке, но и перехвата не будет. Сверьтесь с именем из справки по объекту.
  • ❌ Расширение не обновлено в базе. Заимствованный объект добавлен, но обновление конфигурации БД не выполнено.
  • ❌ Расширение отключено. Загляните в список расширений и проверьте флаг «Активно». Часто его снимают при диагностике и забывают вернуть.
  • ❌ Отсутствует директива &НаКлиенте или &НаСервере у процедуры формы. Тогда она вызывается не там, где ожидалось.
  • ❌ Перехватываемая процедура недоступна. Закрытые процедуры типовых модулей, как правило, перехватить нельзя, а вызывать их напрямую из расширения нельзя тем более. Ищите экспортную процедуру или событие.

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

Частые вопросы

Можно ли редактировать модуль объекта основной конфигурации через расширение?
Прямо — нет. Расширение не меняет код оригинала, оно добавляет вызовы до, после или вместо процедур оригинала. Сам исходный код остаётся нетронутым.
Можно ли в расширении полностью заменить штатную процедуру?
Можно аннотацией &Вместо, если не вызывать оригинал через ПродолжитьВызов. Это рискованно: пропадёт типовая логика. Используйте только когда без полной замены нельзя.
Что делать, если процедура, которую нужно перехватить, недоступна для расширения?
Поищите событие объекта или подписку на событие рядом с этой логикой. Либо перехватите вызывающую процедуру, у которой есть нужные аннотации.
Будет ли расширение работать после обновления типовой конфигурации?
Чаще всего да, если заимствованные объекты и процедуры не менялись. После обновления проверьте расширение на копии базы и посмотрите, нет ли сообщений о несовместимости.
Нужно ли отключать расширение перед обновлением?
Не обязательно. Но на тестовой копии лучше провести обновление с включённым расширением и проверить, что оно загружается без ошибок.