Часто при разработке в 1С возникает задача немного изменить типовую логику, например, добавить дополнительную строку или колонку в печатную форму документа. Современный подход диктует использование расширений конфигурации. Однако, когда разработчик переносит типовую функцию в расширение, платформа автоматически генерирует директиву &Вместо и вставляет метод ПродолжитьВызов(). Разберем по шагам, что с этим делать и как правильно модифицировать код, не навредив системе.
Когда мы добавляем метод в расширение с типом вызова Вызывать вместо, платформа генерирует следующий каркас:
&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(ВыборкаДетальныхЗаписей, ДанныеДокумента, СтруктураПредставленийУчастников, Макет, ТаблицаЗадолженности, ТекущийПартнер, ТекущийДоговор)
// Вставить содержимое метода.
Результат = ПродолжитьВызов(ВыборкаДетальныхЗаписей, ДанныеДокумента, СтруктураПредставленийУчастников, Макет, ТаблицаЗадолженности, ТекущийПартнер, ТекущийДоговор);
Возврат Результат;
КонецФункции
Проанализируем ситуацию. Платформа говорит: «Твоя функция перехватила управление. Теперь ты решаешь, что делать». Функция ПродолжитьВызов() — это, по сути, обращение к оригинальной, типовой функции конфигурации. У вас есть несколько вариантов дальнейших действий.
Самое очевидное (и самое опасное) решение — удалить строку ПродолжитьВызов(), скопировать весь код из типовой функции и вставить его в расширение, добавив свои изменения. Примерно так:
&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
// Весь скопированный код типовой конфигурации
// + Наши 2 строчки кода
Возврат Результат;
КонецФункции
Почему это плохая практика? Главный минус проявляется при обновлениях. Если поставщик конфигурации исправит ошибку в оригинальной функции или добавит новую логику, ваше расширение этого «не заметит». Оно продолжит подменять новую, исправленную функцию вашим старым скопированным кодом. Это часто приводит к неверным расчетам, скрытым багам и падениям системы.
Гораздо безопаснее использовать метод ПродолжитьВызов(). Рассмотрим подробнее этот алгоритм. Суть в том, чтобы дать типовой функции полностью отработать, сформировать печатную форму (например, табличный документ), а затем вмешаться в готовый результат.
&Вместо.ПродолжитьВызов() и получаем готовый результат.Посмотрим на пример:
&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
// 1. Получаем типовой результат
ТабличныйДокумент = ПродолжитьВызов(...);
// 2. Модифицируем (например, добавляем строку вниз или меняем ячейку)
// ТабличныйДокумент.Область("R10C2").Текст = "Наша доп. строка";
// 3. Возвращаем измененный вариант
Возврат ТабличныйДокумент;
КонецФункции
Этот метод делает код максимально независимым от будущих обновлений платформы и конфигурации.
Что делать, если нам нужно изменить логику прямо в середине огромного цикла, и постобработка не подходит? Выясним, как работает аннотация &ИзменениеИКонтроль. Эта директива позволяет не копировать функцию целиком, а точечно менять в ней участки кода с помощью препроцессора.
Внутри функции разработчик использует инструкции: #Удаление, #Вставка, #КонецВставки и #КонецУдаления.
&ИзменениеИКонтроль("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
// ... часть оригинального кода ...
#Удаление
Сумма = ДанныеДокумента.Сумма * 1.2; // Удаляем типовой расчет
#КонецУдаления
#Вставка
Сумма = ДанныеДокумента.Сумма * 1.5; // Вставляем свой расчет
#КонецВставки
// ... продолжение оригинального кода ...
КонецФункции
В чем магия слова «Контроль»? Платформа запоминает исходный текст типовой функции. Если при обновлении базы разработчик 1С изменит эту функцию, платформа при запуске выдаст ошибку, что оригинальный код изменен, и расширение не будет применено. Это заставит программиста вручную зайти, проанализировать изменения и актуализировать свой код, спасая базу от непредсказуемых последствий «тихих» ошибок.
Если ваша задача не требует изменения самой логики внутри функции, всегда старайтесь использовать менее инвазивные директивы:
&Перед — позволяет перехватить параметры до того, как они попадут в оригинальную функцию. Полезно, если нужно подменить входные данные.&После — выполняет ваши действия сразу после оригинальной функции (не возвращая результат, если это процедура). Идеально для работы с глобальными переменными или документами, переданными по ссылке.Часто возникает вопрос: делать печатную форму через расширение или создать классическую ВПФ? У обоих подходов есть плюсы:
Выбор инструмента зависит от конкретной бизнес-задачи, но понимание механизмов ПродолжитьВызов() и &ИзменениеИКонтроль является обязательным для современного разработчика 1С.