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