Как добавить новую колонку в Дерево цен обработки Прайс-лист в 1С:УТ 11?

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

При доработке типовых конфигураций, таких как «Управление торговлей 11», программисты часто сталкиваются с задачей добавления собственных полей на формы сложных обработок. Одной из таких обработок является рабочее место «Прайс-лист». Рассмотрим ситуацию: нам необходимо добавить новую колонку Продолжительность в реквизит формы ДеревоЦен, заполнить её данными из нашего регистра сведений и обеспечить сохранение изменений.

Проанализируем проблему, с которой столкнулся автор: колонка визуально добавляется, но при обновлении данных или закрытии окна настроек возникают ошибки, либо колонка просто исчезает, а данные не заполняются. Выясним причину такого поведения и разберем по шагам правильный алгоритм решения.

Архитектура механизма ценообразования: почему колонка исчезает?

В УТ 11 рабочее место по установке цен очень тесно интегрировано с подсистемой компоновки данных (СКД) и общим модулем УстановкаЦенСервер. При нажатии кнопки «ОК» в форме настроек срабатывает процедура ПерейтиКУстановкеЦен(), которая запускает серверные методы построения дерева.

Главная «ловушка» заключается в том, что типовой механизм 1С при каждом пересчете цен или изменении настроек полностью очищает реквизиты формы. Система удаляет все динамически созданные колонки дерева и генерирует их заново на основе выбранных видов цен. Если вы программно создали колонку только при открытии формы (в ПриСозданииНаСервере), то после вызова типового перестроения интерфейса она будет уничтожена. При попытке вернуть данные с сервера на форму с помощью ЗначениеВРеквизитФормы система выдаст ошибку несоответствия структуры.

Шаг 1. Контролируемое создание колонки на форме

Чтобы избежать ошибок, нам необходимо встроить создание нашей колонки в жизненный цикл формы. Посмотрим на пример того, как перехватить перестроение дерева (например, в процедуре применения настроек):

  1. Сначала мы принудительно удаляем нашу колонку, если она осталась на форме, чтобы избежать конфликтов имен.
  2. Даем отработать типовому коду 1С по формированию ДеревоЦен.
  3. Сразу после этого программно создаем колонку заново и добавляем её в элементы формы.

&НаСервере
Процедура ПослеПримененияНастроек()
    // 1. Удаляем колонку, если она осталась от предыдущих действий
    УдалитьМоюКолонку();
    
    // 2. Вызываем типовой метод перестроения дерева (типовой код 1С)
    ПерейтиКУстановкеЦен(); // или другая вызываемая процедура
    
    // 3. Создаем колонку заново
    СоздатьМоюКолонку();
    
    // 4. Заполняем колонку данными из базы
    ЗаполнитьПродолжительностьВДереве();
КонецПроцедуры

Рассмотрим подробнее реализацию процедуры создания реквизитов и элементов формы с помощью метода ИзменитьРеквизиты:


&НаСервере
Процедура СоздатьМоюКолонку()
    // Формируем массив добавляемых реквизитов
    НовыеРеквизиты = Новый Массив;
    ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2));
    НовыеРеквизиты.Добавить(Новый РеквизитФормы("Продолжительность", ТипЧисло, "ДеревоЦен", "Продолжительность"));
    
    // Применяем изменения к форме
    ИзменитьРеквизиты(НовыеРеквизиты);
    
    // Добавляем элемент управления в таблицу на форме
    ЭлементДерева = Элементы.ДеревоЦен;
    НовыйЭлемент = Элементы.Добавить("ДеревоЦенПродолжительность", Тип("ПолеФормы"), ЭлементДерева);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "ДеревоЦен.Продолжительность";
КонецПроцедуры

Шаг 2. Заполнение добавленной колонки данными

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

Разберем алгоритм заполнения:

  1. Преобразуем данные формы в классическое дерево значений с помощью РеквизитФормыВЗначение.
  2. Собираем массив ссылок на номенклатуру (и характеристики), которые присутствуют в строках дерева.
  3. Выполняем один простой запрос к вашему кастомному регистру сведений с отбором по этому массиву товаров.
  4. Обходим строки дерева (с учетом иерархии) и проставляем полученные значения в колонку Продолжительность.
  5. Загружаем обновленное дерево обратно на форму методом ЗначениеВРеквизитФормы.

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

Шаг 3. Сохранение изменений в базу данных

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

1. Мгновенное сохранение:
При программном создании элемента формы (на шаге 1) мы можем назначить ему обработчик события ПриИзменении с помощью метода УстановитьДействие. Когда пользователь отредактирует ячейку, будет вызван серверный метод, который прочитает свойство Элементы.ДеревоЦен.ТекущиеДанные, получит ссылку на номенклатуру, новое значение продолжительности и точечно запишет набор записей в независимый регистр сведений.

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

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

← На главную