Как добавить объект в расширение 1С и безопасно использовать директиву &Вместо?

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

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

Добавление объектов в расширение: мифы и реальность "одним движением"

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

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

Тем не менее, существует подход, который позволяет относительно быстро добавить необходимые элементы, используемые в объекте:

  1. Добавление формы объекта в расширение. Мы начинаем не с самого документа, а с его формы. Откройте нужный документ (или другой объект, например, справочник) в конфигураторе, перейдите к его основной форме (или любой другой, которую вы планируете изменять). Выберите эту форму в дереве объектов и добавьте ее в ваше расширение. Это действие переносит *только* форму в расширение, но не реквизиты объекта, к которым форма обращается.
  2. Подтягивание реквизитов формы. После того как форма добавлена в расширение, она отобразится в дереве объектов расширения. Откройте эту форму в редакторе. Затем, на любом элементе формы, который представляет реквизит объекта (например, поле ввода, отображающее реквизит документа или табличной части), нажмите правой кнопкой мыши (ПКМ). В контекстном меню выберите пункт "Добавить в расширение" (или аналогичный, зависящий от версии платформы). Платформа проанализирует форму и подтянет все реквизиты, которые используются на этой форме, в расширение. Это значительно упрощает процесс, поскольку вам не придется вручную добавлять каждый реквизит, который вы планируете использовать или изменять.

Важно понимать: платформа подтянет только те реквизиты, которые *используются* на форме. Если у документа есть реквизиты, не выведенные на форму, они не будут автоматически добавлены в расширение этим способом. Их придется добавлять вручную по мере необходимости через соответствующий интерфейс конфигуратора. Например, если вам нужен реквизит Основание, который не отображен на форме, вам нужно будет вручную добавить его в объект расширения через свойства объекта расширения.

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

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

Безопасное использование директивы &Вместо: когда и как применять ПродолжитьВызов()

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

Разберем сценарий, когда мы хотим добавить метод из модуля менеджера документа (или любого другого модуля) с директивой &Вместо, чтобы доработать его логику:

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

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


&Вместо("Процедура ПриОткрытии()")
Процедура Расширение_ПриОткрытии()
    // Здесь мы можем выполнить какой-то код ДО вызова типовой процедуры.
    // Например, проверить некоторые условия или изменить входные параметры.
    Сообщить("Выполняется код расширения ПЕРЕД типовой процедурой.");

    // Вызываем оригинальную процедуру "ПриОткрытии()" из типовой конфигурации.
    // Если оригинальная процедура принимала параметры, ПродолжитьВызов() их автоматически передаст.
    ПродолжитьВызов(); 

    // Здесь мы можем выполнить какой-то код ПОСЛЕ вызова типовой процедуры.
    // Например, модифицировать результат работы типовой процедуры или добавить новые элементы на форму.
    Сообщить("Выполняется код расширения ПОСЛЕ типовой процедуры.");
КонецПроцедуры

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

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

Рекомендации по использованию &Вместо:

  1. Минимизируйте использование: Старайтесь избегать &Вместо там, где можно обойтись директивами &Перед или &После. Эти директивы безопаснее, так как они не замещают оригинальный код, а лишь дополняют его до или после выполнения, не требуя вызова ПродолжитьВызов(). Для функций директивы &Перед и &После недоступны, поэтому &Вместо может быть единственным способом расширения функций.
  2. Всегда используйте ПродолжитьВызов(): Если &Вместо все же необходима, почти всегда следует вызывать ПродолжитьВызов(). Это позволяет сохранить типовую логику и поддерживать возможность ее обновления. Отсутствие вызова ПродолжитьВызов() должно быть осознанным решением, когда вы точно знаете, что типовой код должен быть полностью замещен.
  3. Внимательно отслеживайте обновления: После каждого обновления типовой конфигурации тщательно проверяйте работу расширений, использующих &Вместо. Изменения в оригинальном методе могут нарушить вашу логику, даже если вы используете ПродолжитьВызов(), из-за изменения контекста или входных/выходных параметров.
  4. Рассмотрите &ИзменениеИКонтроль: Для точечных изменений внутри метода, платформа 1С предоставляет аннотацию &ИзменениеИКонтроль. Она позволяет с помощью директив препроцессора #Вставка и #Удаление более гранулярно модифицировать код, не переопределяя метод целиком. Этот подход считается более безопасным, хотя и требует ручной проверки возможности применения расширения после каждого обновления, так как платформа не всегда выдаст предупреждение, если код оригинальной процедуры существенно изменился. Каждый метод конфигурации может быть расширен с помощью &ИзменениеИКонтроль только один раз.

Взаимодействие нескольких расширений

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

Без использования ПродолжитьВызов() в одном из верхних расширений цепочка вызовов прервется, и нижестоящие расширения (и, конечно, типовой метод) могут не быть выполнены. Это подчеркивает важность ответственного подхода при работе с директивой &Вместо, особенно в сложных системах с множеством доработок.

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

← На главную