Как доработать печатную форму в 1С с помощью расширений и аннотации &Вместо?

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

Часто при разработке в 1С возникает задача немного изменить типовую логику, например, добавить дополнительную строку или колонку в печатную форму документа. Современный подход диктует использование расширений конфигурации. Однако, когда разработчик переносит типовую функцию в расширение, платформа автоматически генерирует директиву &Вместо и вставляет метод ПродолжитьВызов(). Разберем по шагам, что с этим делать и как правильно модифицировать код, не навредив системе.

Понимание аннотации &Вместо и метода ПродолжитьВызов()

Когда мы добавляем метод в расширение с типом вызова Вызывать вместо, платформа генерирует следующий каркас:


&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(ВыборкаДетальныхЗаписей, ДанныеДокумента, СтруктураПредставленийУчастников, Макет, ТаблицаЗадолженности, ТекущийПартнер, ТекущийДоговор)
    // Вставить содержимое метода.
    Результат = ПродолжитьВызов(ВыборкаДетальныхЗаписей, ДанныеДокумента, СтруктураПредставленийУчастников, Макет, ТаблицаЗадолженности, ТекущийПартнер, ТекущийДоговор);
    Возврат Результат;
КонецФункции

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

Подход 1: Полное копирование кода (почему так делать не стоит)

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


&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
    // Весь скопированный код типовой конфигурации
    // + Наши 2 строчки кода
    Возврат Результат;
КонецФункции

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

Подход 2: Постобработка результата (безопасный метод)

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

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

Посмотрим на пример:


&Вместо("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
    
    // 1. Получаем типовой результат
    ТабличныйДокумент = ПродолжитьВызов(...);
    
    // 2. Модифицируем (например, добавляем строку вниз или меняем ячейку)
    // ТабличныйДокумент.Область("R10C2").Текст = "Наша доп. строка";
    
    // 3. Возвращаем измененный вариант
    Возврат ТабличныйДокумент;
КонецФункции

Этот метод делает код максимально независимым от будущих обновлений платформы и конфигурации.

Подход 3: Использование &ИзменениеИКонтроль

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

Внутри функции разработчик использует инструкции: #Удаление, #Вставка, #КонецВставки и #КонецУдаления.


&ИзменениеИКонтроль("ВывестиДетальныеЗаписи")
Функция ДорФ_ВывестиДетальныеЗаписи(...)
    
    // ... часть оригинального кода ...
    
    #Удаление
    Сумма = ДанныеДокумента.Сумма * 1.2; // Удаляем типовой расчет
    #КонецУдаления
    
    #Вставка
    Сумма = ДанныеДокумента.Сумма * 1.5; // Вставляем свой расчет
    #КонецВставки
    
    // ... продолжение оригинального кода ...
КонецФункции

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

Другие полезные директивы: &Перед и &После

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

Расширения или Внешние Печатные Формы (ВПФ)?

Часто возникает вопрос: делать печатную форму через расширение или создать классическую ВПФ? У обоих подходов есть плюсы:

Выбор инструмента зависит от конкретной бизнес-задачи, но понимание механизмов ПродолжитьВызов() и &ИзменениеИКонтроль является обязательным для современного разработчика 1С.

← На главную