Как программно заполнить цены в открытом документе Установка цен номенклатуры в УТ 11

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

При разработке внешних обработок заполнения для конфигурации «Управление торговлей 11» (или ERP и КА) программисты часто сталкиваются с проблемой: данные в табличной части программно меняются, но на экране пользователя ничего не происходит. Особенно остро эта проблема проявляется в документе УстановкаЦенНоменклатуры. Рассмотрим подробнее, почему стандартные методы обновления формы не всегда работают и как правильно реализовать заполнение цен, чтобы пользователь сразу увидел результат.

В чем заключается основная сложность документа Установка цен номенклатуры

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

Эта структура строится как кросс-таблица: в строках находится номенклатура, а в колонках — виды цен. Сами колонки создаются программно при открытии формы или выборе видов цен. Когда мы программно перебираем Объект.Товары и меняем там реквизит Цена, визуальный элемент формы (дерево) об этом «не знает» и продолжает отображать старые значения, кэшированные при открытии.

Способ 1. Заполнение через запись и перечитывание формы

Самый надежный, хотя и не самый «чистый» с точки зрения UX способ — это принудительная запись объекта в базу данных с последующим обновлением формы. Рассмотрим этот вариант на примере кода внешней обработки.

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


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

&НаСервере
Процедура ЗаполнитьИЗаписатьНаСервере(СсылкаНаДок)
    ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
    
    Для Каждого Стр Из ДокОбъект.Товары Цикл
        // Например, установим цену 100 для определенного вида цены
        Если Стр.ВидЦены.Наименование = "Оптовая" Тогда
            Стр.Цена = 100;
        КонецЕсли;
    КонецЦикла;
    
    ДокОбъект.Записать();
КонецПроцедуры

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

Способ 2. Заполнение без записи через механизм ЗаполнениеФормы

Для более элегантного решения, которое позволит заполнить форму без обязательной записи в БД, следует использовать механизм БСП ДополнительныеОтчетыИОбработки с типом команды ЗаполнениеФормы. В этом случае в обработку передается параметр ЭтаФорма, предоставляющий доступ к экранным данным.

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


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

Теперь в модуле обработки (не в форме!) реализуем процедуру ВыполнитьКоманду. Здесь мы можем манипулировать данными формы напрямую через ДанныеФормыВЗначение:


Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив, ПараметрыВыполнения) Экспорт
    
    ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
    ОбъектДокумента = ФормаДокумента.Объект;
    
    // Переносим данные формы в объект для удобной работы
    ДокОбъект = ДанныеФормыВЗначение(ОбъектДокумента, Тип("ДокументОбъект.УстановкаЦенНоменклатуры"));
    
    Для Каждого Стр Из ДокОбъект.Товары Цикл
        Стр.Цена = Стр.Цена * 1.1; // Увеличим все цены на 10%
    КонецЦикла;
    
    // Возвращаем измененные данные обратно в форму
    ЗначениеВДанныеФормы(ДокОбъект, ФормаДокумента.Объект);
    
    // Сообщаем форме, что данные изменились (звездочка в заголовке)
    ФормаДокумента.Модифицированность = Истина;
    
    // А теперь — самое главное! Обновление визуального дерева.
    // В типовых УТ 11 в форме документа есть экспортные методы пересчета.
    Попытка
        ФормаДокумента.ОбновитьОтображениеЦен(); 
    Исключение
        // Если метод не экспортный или называется иначе, 
        // потребуется имитация изменения ключевых реквизитов
    КонецПопытки;
    
КонецПроцедуры

Почему цены все равно могут не отобразиться?

Проанализируем ситуацию, если вы применили ЗначениеВДанныеФормы, но таблица на экране осталась пустой или со старыми ценами. В типовых конфигурациях 1С обновление ДереваЦен (той самой кросс-таблицы) завязано на серверные процедуры модуля формы.

Рассмотрим основные причины:

  1. Динамические колонки: Колонки в дереве имеют имена вида Цена_<УникальныйИдентификаторВидаЦены>. Если вы просто меняете ТЧ Товары, дерево не перестраивается автоматически.
  2. Отсутствие вызова обработчика обновления: В модуле формы УстановкаЦенНоменклатуры обычно есть процедура ЗаполнитьДеревоЦен() (или аналогичная). Если она не является экспортной, вы не сможете вызвать её из внешней обработки напрямую.

Совет: Если штатные методы обновления недоступны, можно попробовать «взломать» систему, программно изменив какой-нибудь реквизит формы, на который «подписано» обновление (например, перевыбрать виды цен программно), но это требует глубокого анализа кода конкретного релиза конфигурации.

Итоги

Для корректного программного заполнения документа «Установка цен номенклатуры» в управляемом интерфейсе УТ 11 мы рекомендуем:

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

← На главную