Как переопределить процедуру формы документа в расширении конфигурации 1С?

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

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

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

Рассмотрим частую ошибку, когда в форму расширения добавляется процедура с префиксом расширения, например:


&НаКлиенте
Процедура даг_ПробитьЧекЗавершение(Результат, ДополнительныеПараметры) Экспорт
    // Пользовательский код обработки завершения
КонецПроцедуры

Если в типовой конфигурации вызов осуществляется асинхронно через объект ОписаниеОповещения, инициатор операции обращается к процедуре по ее оригинальному строковому имени ("ПробитьЧекЗавершение"). Простое добавление нового метода с префиксом даг_ не связывает его с типовым алгоритмом. Платформа продолжает вызывать исходную процедуру формы, игнорируя созданный метод.

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

Решение 1. Использование аннотаций перехвата вызовов методов (&Вместо, &Перед, &После)

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

Разберем доступные аннотации перехвата:

  1. &Вместо("<ИмяМетода>") — полностью перекрывает выполнение типового метода. Вместо оригинальной процедуры выполняется код расширения. При необходимости вызвать оригинальную логику из тела перехватчика используется оператор ПродолжитьВызов().
  2. &Перед("<ИмяМетода>") — выполняет код расширения непосредственно перед запуском типовой процедуры.
  3. &После("<ИмяМетода>") — запускает метод расширения сразу после завершения выполнения оригинальной процедуры.

Посмотрим на пример правильного переопределения процедуры обратного вызова в модуле расширения формы:


&НаКлиенте
&Вместо("ПробитьЧекЗавершение")
Процедура даг_ПробитьЧекЗавершение(Результат, ДополнительныеПараметры)
    Если Результат.ВыполненаОперацияНаУстройстве И Результат.ИзмененныеДанныеЗаписаны Тогда
        ТолькоПросмотр = Истина;
        ЗагрузитьНовыйЧек();
    ИначеЕсли Результат.ВыполненаОперацияНаУстройстве И Не Результат.ИзмененныеДанныеЗаписаны Тогда
        ПараметрыФормы = Новый Структура;
        ПараметрыФормы.Вставить("Данные", Объект.Ссылка);
        ПараметрыФормы.Вставить("ДанныеДляЖурналаРегистрации", ДанныеДляЖурналаРегистрации);
        ПараметрыФормы.Вставить("ТекстСообщения", НСтр("ru = 'ВНИМАНИЕ! Чек пробит, но не зафиксирован в системе.'"));
        ОткрытьФорму("Документ.ЧекККМ.Форма.ОшибкаЗаписи", ПараметрыФормы, ЭтотОбъект);
    КонецЕсли;
КонецПроцедуры

Важные правила при использовании аннотаций перехвата:

  1. Директива контекста исполнения (&НаКлиенте, &НаСервере, &НаСервереБезКонтекста) у метода в расширении обязана в точности совпадать с директивой перехватываемого метода.
  2. Количество, порядок и имена параметров процедуры перехватчика должны полностью соответствовать оригинальной процедуре.
  3. Режим совместимости основной конфигурации и расширения должен быть установлен не ниже «Версия 8.3.9». Если в конфигурации включен режим совместимости 8.3.8 или ниже, директивы перехвата компилироваться не будут.

Решение 2. Переопределение обработчиков событий формы и команд

Если необходимо переопределить стандартное событие формы (например, ПриСозданииНаСервере) или команду, заимствованную в расширение, важно помнить о привязке обработчика:

  1. Если создается новая процедура-обработчик с собственным именем (например, даг_ПриСозданииНаСервере), необходимо в свойствах формы расширения в палитре свойств явно привязать событие ПриСозданииНаСервере к новой процедуре.
  2. Если используется перехват через &После("ПриСозданииНаСервере") или &Перед("ПриСозданииНаСервере"), явная привязка в свойствах не требуется — платформа свяжет вызовы автоматически по имени аннотации.

Рассмотрим пример добавления условного оформления динамических данных при открытии формы с использованием аннотации &После:


&НаСервере
&После("ПриСозданииНаСервере")
Процедура даг_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    даг_ОформитьТабличнуюЧасть();
КонецПроцедуры

&НаСервере
Процедура даг_ОформитьТабличнуюЧасть()
    // Пользовательская логика настройки условного оформления
    ЭлементУО = УсловноеОформление.Элементы.Добавить();
    ПолеУО = ЭлементУО.Поля.Элементы.Добавить();
    ПолеУО.Поле = Новый ПолеКомпоновкиДанных("Товары");
    
    ЭлементОтбора = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.Количество");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно;
    ЭлементОтбора.ПравоеЗначение = 0;
    
    ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветТекста", WebЦвета.Красный);
КонецПроцедуры

Решение 3. Точечное изменение логики с помощью &ИзменениеИКонтроль (для платформы 8.3.15 и выше)

Если на проекте используется современная версия платформы (8.3.15 и новее) с соответствующим режимом совместимости, вместо полного перекрытия через &Вместо рекомендуется применять аннотацию &ИзменениеИКонтроль("<ИмяМетода>").

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

← На главную