Как настроить путь к данным колонки по условию для группы и элемента в управляемой форме 1С?

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

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

Ограничения платформы: почему нельзя настроить свойствами элементов

Попытка настроить такое поведение исключительно через палитру свойств элементов формы сталкивается со следующими особенностями архитектуры управляемых форм:

  1. Статичность свойства ПутьКДанным. Свойство элемента формы ПутьКДанным содержит строго фиксированную строку, указывающую на реквизит данных формы. Платформа 1С не поддерживает вычисление выражений, условий или тернарных операторов в этом свойстве.
  2. Невозможность скрыть отдельную ячейку. Свойство Видимость применяется только ко всей колонке таблицы целиком. В механизме УсловноеОформление нет возможности скрыть конкретную ячейку в одной строке, оставив её видимой в другой.
  3. Ограничения условного оформления по замене текста. Параметр Текст в условном оформлении принимает только фиксированный литерал и не может динамически брать значение из другого реквизита строки.
  4. Отсутствие построчной отрисовки на клиенте. В управляемых формах нет событий вроде ПриВыводеСтроки, которые применялись в обычном приложении. Данные передаются на клиент целиком в составе контекста формы.

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

Способ 1. Добавление реквизита формы и обработка событий

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

Разберем по шагам порядок действий:

  1. Открываем форму документа в конфигураторе и переходим на вкладку Реквизиты.
  2. В составе табличной части объекта (или отдельной таблицы формы) добавляем новый реквизит формы, например, с именем ПредставлениеРеквизитаСерии строкового или составного типа.
  3. Перетаскиваем созданный реквизит в элементы таблицы формы — создается колонка с фиксированным путем к данным.
  4. Настраиваем заполнение значения при интерактивном изменении серии пользователем.

Чтобы не перебирать всю таблицу целиком при каждом редактировании строки, проанализируем событие поля ввода серии. В событии СерияПриИзменении достаточно обновить значение только для текущей строки таблицы:


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

На стороне сервера реализуем проверку на группу и чтение нужного значения:


&НаСервереБезКонтекста
Функция ПолучитьЗначениеРеквизитаСерии(СсылкаНаСерию)
    
    Если Не ЗначениеЗаполнено(СсылкаНаСерию) Тогда
        Возврат "";
    КонецЕсли;
    
    Если СсылкаНаСерию.ЭтоГруппа Тогда
        Возврат СсылкаНаСерию.РеквизитГруппы;
    Иначе
        Возврат СсылкаНаСерию.РеквизитЭлемента;
    КонецЕсли;
    
КонецФункции

Способ 2. Оптимизированное пакетное заполнение при открытии формы

Если в документе уже сохранены строки, добавленную колонку необходимо заполнить при открытии формы. Полный проход по строкам с вызовом обращений к базе данных через точку приведет к проблеме «запрос в цикле». Рассмотрим, как заполнить данные одним запросом в серверном обработчике ПриЧтенииСозданииНаСервере:


&НаСервере
Процедура ЗаполнитьКолонкуСерийНаСервере()
    
    Таблица = Объект.ТабличнаяЧасть.Выгрузить();
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ВремТаблица.НомерСтроки КАК НомерСтроки,
        |	ВЫБОР
        |		КОГДА СправочникСерии.ЭтоГруппа
        |			ТОГДА СправочникСерии.РеквизитГруппы
        |		ИНАЧЕ СправочникСерии.РеквизитЭлемента
        |	КОНЕЦ КАК ВычисленноеЗначение
        |ИЗ
        |	&ТаблицаДанных КАК ВремТаблица
        |	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Серии КАК СправочникСерии
        |		ПО ВремТаблица.Серия = СправочникСерии.Ссылка";
        
    Запрос.УстановитьПараметр("ТаблицаДанных", Таблица);
    Результат = Запрос.Выполнить().Выгрузить();
    
    Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть Цикл
        НайденнаяСтрока = Результат.Найти(СтрокаТЧ.НомерСтроки, "НомерСтроки");
        Если НайденнаяСтрока <> Неопределено Тогда
            СтрокаТЧ.ПредставлениеРеквизитаСерии = НайденнаяСтрока.ВычисленноеЗначение;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Архитектурная альтернатива в структуре метаданных

Если конфигурация находится в разработке или открыта для изменения, проанализируем возможность устранения разделения реквизитов на уровне метаданных справочника:

  1. Открываем свойства нужного реквизита в справочнике Серии.
  2. Находим свойство Использование.
  3. Устанавливаем переключатель в положение Для элемента и группы вместо раздельных реквизитов.

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

← На главную