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