Почему пропадают данные при заполнении документа в расширении через ОбработкаЗаполнения?

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

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

Анализ механизма работы ОбработкаЗаполнения в расширениях

Рассмотрим стандартный жизненный цикл создания объекта. Когда мы инициируем создание документа на основании другого объекта, платформа выполняет процедуру ОбработкаЗаполнения в модуле объекта. Если мы используем расширение с директивой &После (After), наш код выполняется в самом конце цепочки. Казалось бы, данные уже должны быть окончательно сформированы. Однако на практике возникает эффект «фиксации» состояния.

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

Решение 1: Переход на использование директивы &Вместо

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

  1. Скопируем полностью текст типовой процедуры ОбработкаЗаполнения из основной конфигурации.
  2. Вставим его в модуль объекта в расширении.
  3. Добавим в конце (перед завершением процедуры) свой блок кода для модификации табличных частей.

Пример реализации в расширении:


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

Решение 2: Проверка событий на стороне формы

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

  1. Выполняется ОбработкаЗаполнения в модуле объекта (основная конфигурация + расширения).
  2. Выполняется ОбработкаЗаполнения в модуле формы.
  3. Выполняется ПриСозданииНаСервере в модуле формы.

Если в основной конфигурации в коде формы прописана логика, которая пересчитывает цены, проверяет остатки или очищает «некорректные» с точки зрения типового алгоритма строки, ваши изменения из расширения будут потеряны. Проверим наличие вызовов типа ЗаполнитьЗначенияСвойств или ЗначениеВРеквизитФормы(НовыйОбъект, "Объект") в процедуре ПриСозданииНаСервере. Если такие вызовы присутствуют, они могут заново инициализировать данные из «чистого» объекта.

Решение 3: Использование структуры ДополнительныеСвойства

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

Разберем алгоритм действий:

  1. В расширении модуля объекта (в ОбработкаЗаполнения) записываем нужные данные в структуру:
    
    ЭтотОбъект.ДополнительныеСвойства.Вставить("ДанныеДляТЧ_Расширение", МояТаблицаЗначений);
    
  2. В расширении модуля формы (в ПриСозданииНаСервере с директивой &После) извлекаем эти данные и принудительно заполняем реквизит формы:
    
    &После("ПриСозданииНаСервере")
    Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        Если Объект.ДополнительныеСвойства.Свойство("ДанныеДляТЧ_Расширение") Тогда
            // Заполняем ТЧ формы из сохраненных данных
            Объект.Товары.Загрузить(Объект.ДополнительныеСвойства.ДанныеДляТЧ_Расширение);
        КонецЕсли;
    КонецПроцедуры
    

Решение 4: Проверка прав доступа и функциональных опций

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

  1. Роли в расширении: Убедимся, что для пользователя создана или расширена роль, дающая право на чтение и просмотр новых реквизитов.
  2. Функциональные опции: Если реквизиты ТЧ привязаны к функциональным опциям, которые выключены в текущем сеансе, платформа отсечет эти данные при отрисовке формы.

Решение 5: Отладка через замер производительности

Если причину найти не удается, воспользуемся инструментом «Замер производительности». Это позволит точно увидеть, какие строки кода выполняются между моментом заполнения в модуле объекта и моментом отображения в ПриСозданииНаСервере. Проанализируем замер на предмет:

Подводя итог, отметим, что наиболее стабильным решением в 90% случаев является использование директивы &Вместо для процедуры ОбработкаЗаполнения, так как это минимизирует количество «перерисовок» объекта платформой и гарантирует целостность данных перед передачей в форму.

← На главную