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