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