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