Почему добавленный в расширении реквизит не виден в обработке проведения и движениях?

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

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

Причина 1: Область видимости метаданных и контекст исполнения

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

Рассмотрим, как это работает на практике. Когда вы добавляете реквизит ДополнительнаяСкидка в документ РеализацияТоваровУслуг через расширение, этот реквизит существует только в контексте этого расширения. Чтобы использовать его в коде, сам программный код также должен быть помещен в модуль расширения.

Решение: Перенос логики в расширение через аннотации

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

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

Посмотрим на пример использования аннотации &После для заполнения нового реквизита в движениях:


&После("ОбработкаПроведения")
Процедура Расш1_ОбработкаПроведения(Отказ, РежимПроведения)
    
    // Реквизит "ВажныйКомментарий" добавлен в документ через расширение
    // Реквизит "ДопИнфо" добавлен в РегистрНакопления.Продажи через расширение
    
    Для Каждого Движение Из Движения.Продажи Цикл
        Движение.ДопИнфо = ЭтотОбъект.ВажныйКомментарий;
    КонецЦикла;
    
КонецПроцедуры

Причина 2: Отсутствие реквизита в самом регистре

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

  1. Добавить нужный Регистр в расширение.
  2. В расширении добавить в этот Регистр соответствующий реквизит или ресурс.
  3. Только после этого в коллекции Движения.ИмяРегистра появится нужное поле.

Проанализируем ситуацию: если в расширении есть реквизит документа СрокДоставки, но в регистре Заказы в расширении такого поля нет, то обращение Движение.СрокДоставки вызовет ошибку, даже если код написан внутри расширения.

Причина 3: Проблемы с типизацией в запросах

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

Пример модификации запроса:


// В методе &ИзменениеИКонтроль находим текст запроса
ТекстЗапроса = 
"ВЫБРАТЬ
|   ТЧ.Ссылка,
|   ТЧ.Номенклатура,
|   ТЧ.НовыйРеквизитИзРасширения // Платформа увидит это поле, так как код в расширении
|ИЗ
|   Документ.ЗаказПокупателя.Товары КАК ТЧ";

Рекомендации по отладке и кэшированию

Иногда даже при правильном написании кода платформа продолжает «ругаться» на отсутствие реквизита. Выясним причины такого поведения:

Итоги

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

  1. Добавьте реквизит в Объект (документ) внутри расширения.
  2. Добавьте аналогичный реквизит в Регистр внутри того же расширения.
  3. Перехватите процедуру ОбработкаПроведения в модуле объекта (или менеджера, если логика там) расширения, используя аннотации &После или &ИзменениеИКонтроль.
  4. Пишите код обращения к реквизитам строго внутри модуля расширения.

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

← На главную