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

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

При разработке внешних обработок для заполнения табличных частей (ТЧ) в конфигурациях на управляемых формах, таких как ЗУП 3.1, разработчики часто сталкиваются с ситуацией, когда данные в коде вроде бы добавляются, но после закрытия формы документа табличная часть остается пустой. Давайте разберем, почему это происходит и как правильно передавать данные в управляемую форму.

Разбор причин возникновения проблемы

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

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

Решение проблемы через механизм оповещения

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

  1. Подготовка данных в обработке: Вместо того чтобы напрямую менять объект владельца, сформируйте таблицу значений или структуру, содержащую необходимые данные для заполнения табличных частей.
  2. Передача данных при закрытии: Используйте метод Закрыть(РезультатЗакрытия). В качестве параметра РезультатЗакрытия передайте подготовленную структуру.
  3. Обработка получения данных в форме документа: В форме документа при открытии обработки необходимо использовать метод ОткрытьФорму с указанием процедуры-обработчика оповещения (ОписаниеОповещения).

Пример реализации

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


// В форме обработки
Процедура КомандаПеренестиДанные(Команда)
    // Собираем данные в структуру для передачи
    ДанныеДляПереноса = Новый Структура;
    ДанныеДляПереноса.Вставить("ЗначенияПоказателей", Объект.ЗначенияПоказателей.Выгрузить());
    ДанныеДляПереноса.Вставить("ФизическиеЛица", Объект.ФизическиеЛица.Выгрузить());
    
    // Закрываем форму, возвращая структуру
    Закрыть(ДанныеДляПереноса);
КонецПроцедуры

В форме документа, которая вызывает эту обработку, необходимо организовать прием данных:


// В форме документа
Процедура ВыполнитьЗаполнение()
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияОбработкиЗаполнения", ЭтотОбъект);
    ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма", , , , , , Оповещение);
КонецПроцедуры

Процедура ПослеЗакрытияОбработкиЗаполнения(Результат, Параметры) Экспорт
    Если Результат = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Очищаем существующие данные и загружаем новые из результата
    Объект.ЗначенияПоказателей.Загрузить(Результат.ЗначенияПоказателей);
    Объект.ФизическиеЛица.Загрузить(Результат.ФизическиеЛица);
    
    // Уведомляем систему, что данные объекта были изменены
    Модифицированность = Истина;
КонецПроцедуры

Почему этот способ лучше?

Используя данный подход, вы решаете сразу несколько задач:

Также важно помнить, что после загрузки данных в табличную часть крайне желательно устанавливать свойство Модифицированность = Истина. Это дает платформе сигнал, что форма документа была изменена, и при попытке закрытия документа 1С предложит пользователю сохранить внесенные изменения, что является ожидаемым поведением.

Если же вы все-таки решите использовать прямой доступ к ВладелецФормы, обязательно после внесения изменений вызывайте метод Обновить() для элемента формы (таблицы), однако мы настоятельно рекомендуем придерживаться метода оповещения через ОписаниеОповещения, описанного выше.

← На главную