Как обновить данные на форме документа Установка цен номенклатуры после программного заполнения из внешней обработки

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

При разработке внешних обработок заполнения для современных конфигураций на базе 1С:ERP 2.5 или 1С:Комплексная автоматизация 2.5 программисты часто сталкиваются с ситуацией: данные в табличную часть документа Товары успешно добавлены (что подтверждается отладчиком или выводом количества строк), но на самой форме документа в интерфейсе пользователя таблица остается пустой. Простая команда ВладелецФормы.ОбновитьОтображениеДанных() в этом случае не помогает. Проанализируем ситуацию и разберем по шагам, почему это происходит и как правильно обновить интерфейс.

Выясняем причину: почему данные не отображаются

Первым делом проанализируем структуру формы документа УстановкаЦенНоменклатуры. В отличие от простых документов, где элементы формы напрямую связаны с реквизитами объекта (табличными частями), форма установки цен в КА 2.5 построена гораздо сложнее. На форме отображается не сама табличная часть Товары, а динамически формируемое Дерево Значений.

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

Решение 1: Вызов штатных серверных методов обновления

Наиболее правильный путь с точки зрения архитектуры типового решения — использовать встроенные механизмы конфигурации. В модуле менеджера документа или специализированных серверных модулях (например, УстановкаЦенСервер) существуют процедуры, отвечающие за синхронизацию данных объекта и формы. Рассмотрим, как реализовать это в коде внешней обработки.

Для корректного обновления нам потребуется выполнить следующие действия:

  1. Заполнить табличную часть Товары (это вы уже сделали).
  2. Заполнить табличную часть ВидыЦен, так как без выбранных видов цен дерево не создаст колонки.
  3. Вызвать серверную процедуру загрузки данных в дерево формы.

Пример кода, который необходимо вызвать в контексте формы владельца (через серверный вызов):


&НаСервере
Процедура ОбновитьДанныеНаФормеСервер(ФормаДокумента)
    // Инициализируем структуру кэша, которая необходима для работы процедур заполнения
    КэшДанных = УстановкаЦенСервер.ИнициализироватьСтруктуруКэшаДанных();
    
    // Вызываем штатную процедуру загрузки ТЧ Товары в дерево значений формы
    // Параметр ФормаДокумента — это УправляемаяФорма нашего документа
    УстановкаЦенСервер.ЗагрузитьТабличнуюЧастьТовары(ФормаДокумента, КэшДанных);
КонецПроцедуры

Обратите внимание, что доступ к серверному модулю УстановкаЦенСервер должен быть разрешен. Если вы работаете из внешней обработки, запущенной на клиенте через ВызовКлиентскогоМетода, вам может потребоваться передать управление на сервер формы-владельца или использовать расширение.

Решение 2: Использование механизма оповещений и расширения

Если вы не хотите глубоко внедряться в логику серверных модулей, можно воспользоваться механизмом оповещений БСП. Рассмотрим алгоритм действий:

  1. Во внешней обработке после завершения цикла загрузки данных вызываем команду Оповестить("ПрайсЗагружен", , ВладелецФормы);.
  2. Создаем расширение для формы документа УстановкаЦенНоменклатуры.
  3. В расширении добавляем обработчик события ОбработкаОповещения.

В коде расширения это будет выглядеть следующим образом:


&НаКлиенте
Процедура ИмяРасширения_ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ПрайсЗагружен" Тогда
        // Вызываем штатную процедуру формы, которая перестраивает дерево
        ЭтаФорма.ЗаполнитьДокумент();
    КонецЕсли;
КонецПроцедуры

Процедура ЗаполнитьДокумент() является ключевой на форме установки цен. Она выполняет полный цикл: от анализа текущих настроек компоновки до фактического построения строк дерева на экране.

Решение 3: Правильная регистрация обработки через БСП

Часто проблема с обновлением возникает из-за того, что используется ТипКоманды.ВызовКлиентскогоМетода. В этом режиме разработчик берет на себя всю ответственность за состояние интерфейса. Если изменить тип команды на ЗаполнениеФормы, система будет работать иначе.

При использовании ЗаполнениеФормы логика переносится в модуль объекта обработки в процедуру ВыполнитьКоманду на сервере. В этом случае БСП передает в обработку структуру параметров, включая модифицированный объект. После завершения выполнения команды на сервере, платформа автоматически обновляет форму-владельца, с которой была вызвана команда. Посмотрим на пример настройки СведенияОВнешнейОбработке:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Загрузить из Excel (Сервер)";
    НоваяКоманда.Идентификатор = "ЗагрузитьСервер";
    // Используем ЗаполнениеФормы вместо ВызовКлиентскогоМетода
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
    
    Возврат ПараметрыРегистрации;
КонецФункции

Важный нюанс: Даже при использовании этого метода для документа Установка цен номенклатуры может потребоваться ручной вызов перестроения дерева, так как стандартные механизмы БСП могут не знать о существовании нетипового элемента управления (дерева) на форме.

Разберем типичную ошибку в коде заполнения

Посмотрим на фрагмент кода из вашего сообщения. Вы добавляете данные в ВладелецФормы.Объект.Товары. Это работает, но крайне важно не забывать про ВидыЦен. Если в объекте Товары есть записи с ВидЦены = "Оптовая", но в табличной части документа ВидыЦен этот вид цены отсутствует, форма просто не будет знать, что для этой цены нужно создать колонку.

Проверьте, что вы корректно заполняете коллекцию видов цен:


// Очищаем старые виды цен, если это необходимо по логике
ВладелецФормы.Объект.ВидыЦен.Очистить();

// Добавляем виды цен из файла
Для Каждого ТекВид Из МассивВидовЦен ИзФайла Цикл
    НоваяСтрокаВид = ВладелецФормы.Объект.ВидыЦен.Добавить();
    НоваяСтрокаВид.ВидЦены = ТекВид;
КонецЦикла;

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

Подведем итоги

Проанализировав ситуацию, мы выяснили, что основной проблемой является разрыв между данными объекта и данными формы. Для решения задачи рекомендуем:

  1. Использовать процедуру ЗаполнитьДокумент() формы-владельца — это самый надежный способ "встряхнуть" интерфейс.
  2. Если прямой вызов невозможен, используйте серверные методы модуля УстановкаЦенСервер для обновления дерева.
  3. Всегда проверяйте соответствие загружаемых товаров списку видов цен в документе.

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

← На главную