Как правильно добавить новую функцию в расширение 1С, если её нет в типовой конфигурации?

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

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

Анализ проблемы: почему возникают ошибки аннотаций

Рассмотрим ситуацию, когда программист пытается добавить функцию в расширение, используя аннотации &Перед или &После. В результате платформа выдает ошибку: «Неправильное использование аннотации: аннотацию нельзя применять к функциям». Выясним причину этого поведения платформы.

Аннотации &Перед, &После, &Вместо и &ИзменениеИКонтроль предназначены исключительно для перехвата или модификации уже существующих методов (процедур и функций) основной конфигурации. Если вы пытаетесь применить их к методу, которого нет в основной базе, платформа не находит «цель» для привязки и выдает ошибку.

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

Вариант 1: Добавление абсолютно новой функции

Если ваша задача — добавить уникальную функцию, которой вообще не существует в коде поставщика, запомните главное правило: никакие аннотации использовать не нужно. Рассмотрим алгоритм действий:

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

Проанализируем пример кода в модуле расширения:


// Новая функция, которой нет в типовой БП 3.0
Функция Моя_РассчитатьСпецифическийПоказатель(Параметры) Экспорт
    
    Результат = 0;
    // Здесь ваша логика расчетов
    Возврат Результат;
    
КонецФункции

Важно помнить о префиксах. Чтобы в будущем, когда поставщик выпустит обновление конфигурации, ваше расширение не «сломалось» из-за совпадения имен, всегда добавляйте уникальный префикс к своим функциям (например, ИмяКомпании_ или ПрефиксПроекта_).

Вариант 2: Использование аннотации &Вместо

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


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

Функция Моя_НоваяЛогика(Данные)
    // Описание новой логики, которой нет в конфигурации
КонецФункции

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

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

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

Проанализируем пример использования этой технологии:


&ИзменениеИКонтроль("ТиповаяПроцедура")
Процедура Расш1_ТиповаяПроцедура()
    
    Строка = "Начало";
    #Вставка
    // Вызываем нашу новую функцию прямо внутри типового алгоритма
    Моя_ДополнительнаяОбработка(Строка);
    #КонецВставки
    Запрос = Новый Запрос;
    
КонецПроцедуры

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

Создание собственного общего модуля (Best Practice)

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

  1. Создаем в расширении свой собственный общий модуль (например, Мой_ОбщиеФункции).
  2. Устанавливаем ему нужные флаги видимости (Сервер, Вызов сервера, Клиент).
  3. Все новые функции, которых нет у поставщика, размещаем именно в нем.
  4. В расширениях типовых модулей через &Вместо или &ИзменениеИКонтроль делаем только короткие вызовы функций из вашего нового модуля.

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


&НаКлиенте
&После("ПриОткрытии")
Процедура Расш1_ПриОткрытии(Отказ)
    
    // Обращаемся к нашему новому общему модулю из расширения
    Мой_ОбщиеФункцииКлиент.ВыполнитьДополнительныеДействия(ЭтаФорма);
    
КонецПроцедуры

Такой подход гарантирует, что при обновлении Бухгалтерии предприятия вам нужно будет контролировать только точки входа (аннотированные методы), в то время как основная логика в вашем отдельном модуле останется нетронутой и защищенной от случайных изменений со стороны поставщика. Для автоматизированного контроля вызовов экспортных процедур и функций общих модулей в расширениях можно использовать конфигурацию для анализа расширений на ошибки.

Итоги и рекомендации

Подведем итог нашему разбору. Для успешного добавления кода в расширение соблюдайте следующие правила:

Соблюдение этих принципов позволит вам создавать стабильные и легко обновляемые решения на платформе 1С:Предприятие 8.3.

← На главную