Работа с расширениями в системе «1С:Предприятие 8.3» — это стандарт де-факто для доработки типовых конфигураций. Однако начинающие (и даже опытные) разработчики часто сталкиваются с ситуацией, когда ожидаемое поведение расширенной команды формы не совпадает с реальностью. Типичный сценарий: вы заимствуете форму, добавляете команду в расширение, указываете тип вызова Вместо, но код основной конфигурации всё равно выполняется или срабатывает не в том порядке. Рассмотрим подробнее, почему это происходит и как реализовать надежную проверку перед выполнением типового кода.
Разберем ситуацию, с которой столкнулся автор темы. При заимствовании формы в расширение и попытке изменить свойство Действие у команды в палитре свойств, платформа должна была бы подменить обработчик. На практике часто наблюдается «двойное» выполнение или выполнение кода основной конфигурации вопреки настройкам. Это происходит по нескольким причинам:
ПриСозданииНаСервере. Программная установка свойства Действие имеет приоритет над тем, что вы указали визуально в редакторе формы.Записать или Провести), платформа жестко связывает её с внутренними механизмами, и простая замена обработчика через свойства может игнорироваться.Проанализируем наиболее надежный способ решения задачи. Вместо того чтобы пытаться «переиграть» платформу в визуальном редакторе свойств, мы будем использовать механизм перехвата методов в модуле формы расширения. Это гарантирует, что при вызове процедуры, назначенной команде, управление сначала попадет в наш код.
Рассмотрим пример, когда нам нужно добавить проверку заполнения суммы перед пробитием чека. Выясним причину ошибки: автор пытался менять действие команды, а нужно было менять сам метод. Посмотрим на итоговый правильный код в расширении:
&НаКлиенте
&Вместо("ИмяПроцедурыТиповогоОбработчика")
Процедура РМЦДП_Чек(Команда)
// Наша проверка перед выполнением основного кода
Если Объект.ПолученоНаличными + ОплаченоБезналичным = 0 Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Не указана сумма оплаты!'"));
Возврат; // Прерываем выполнение, типовой код не вызовется
КонецЕсли;
// Если проверка пройдена, вызываем оригинальный код основной конфигурации
ПродолжитьВызов(Команда);
КонецПроцедуры
В данном примере ИмяПроцедурыТиповогоОбработчика — это название процедуры, которая указана в свойстве Действие у команды в основной конфигурации. Мы не меняем само свойство Действие в расширении, мы просто перехватываем выполнение этой процедуры.
Чтобы гарантированно добиться нужного результата, выполним следующие действия:
&НаКлиенте и &Вместо("ИмяОригинальнойПроцедуры").Если ... Тогда ... Возврат; КонецЕсли;.ПродолжитьВызов(), чтобы передать управление дальше по цепочке (в основную конфигурацию или другие расширения).Функция ПродолжитьВызов() является ключевой в механизме расширений. Она позволяет соблюдать принцип матрешки: ваше расширение оборачивает типовой код. Если вы забудете вызвать ПродолжитьВызов(), типовая логика будет полностью подавлена. Это полезно, если вы пишете функционал «с нуля», но опасно, если типовой метод выполняет важные служебные действия (заполнение структур, очистку временных файлов и т.д.).
Проанализируем ситуацию с несколькими расширениями. Если в базе установлено несколько расширений, влияющих на одну и ту же форму, порядок их выполнения будет зависеть от их приоритета (порядка в списке расширений). Использование &Вместо позволяет выстроить четкую иерархию вызовов.
Также стоит помнить о «чистоте» расширения. Если вы заимствовали команду в расширение («пальчиком» перетащили её в дерево метаданных расширения), проверьте, не изменилось ли при этом её свойство Действие автоматически на новую пустую процедуру. Если это произошло, это может стать причиной того, что типовой код перестанет вызываться вообще или будет вызываться некорректно. Самый стабильный вариант — заимствовать форму, а команду оставить «как есть», работая только через перехват процедур в коде модуля.
Таким образом, мы выяснили, что программный перехват методов через аннотации — это гораздо более гибкий и предсказуемый инструмент, чем попытка визуального редактирования свойств заимствованных элементов формы. Этот подход позволяет избежать конфликтов с БСП и обеспечивает корректную работу логики даже после обновления конфигурации.