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