При разработке интерфейсов на обычных формах (толстый клиент), особенно в таких конфигурациях, как Управление торговлей 10.3, разработчики часто сталкиваются с требованием заказчика визуально выделить иерархию в дереве значений. Основная сложность возникает, когда необходимо сохранить тип данных СправочникСсылка в колонке, чтобы пользователь мог стандартным образом открывать карточку объекта, но при этом видеть отступы, соответствующие уровню вложенности строки.
Рассмотрим детально, как решить эту задачу, не прибегая к конвертации данных в строковый тип, и проанализируем основные технические приемы, доступные в платформе 1С.
Самый правильный и производительный способ управления визуальным представлением данных в табличном поле — это использование события ПриВыводеСтроки. В обычных формах у объекта ОформлениеЯчейки есть специализированное свойство Отступ, которое позволяет задать смещение содержимого ячейки вправо.
Разберем реализацию этого метода по шагам:
ПриВыводеСтроки для нашего табличного поля.Отступ для нужной ячейки.Проанализируем пример кода:
Процедура ДеревоГТДПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Получаем текущий уровень строки (0 - верхний уровень, 1 - первый вложенный и т.д.)
УровеньВложенности = ДанныеСтроки.Уровень();
// Определяем множитель отступа (например, 2 единицы на каждый уровень)
Множитель = 4;
// Устанавливаем отступ для колонки "Номенклатура"
// Само значение в ячейке остается ссылкой, но визуально текст смещается
ОформлениеСтроки.Ячейки.Номенклатура.Отступ = УровеньВложенности * Множитель;
КонецПроцедуры
Важно помнить, что свойство Отступ работает только для отображения. Оно не изменяет само значение ДанныеСтроки.Номенклатура, поэтому все функции ссылочного типа (переход в справочник, получение реквизитов) сохраняются в полном объеме.
Если стандартного свойства Отступ недостаточно (например, требуется более сложное форматирование или специфические символы перед названием), мы можем воспользоваться методом УстановитьТекст(). Этот метод позволяет переопределить визуальное представление значения, не меняя само значение в ячейке.
Выясним, как это реализовать, чтобы сохранить возможность "провала" в ссылку:
Процедура ДеревоГТДПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Уровень = ДанныеСтроки.Уровень();
Если Уровень > 0 Тогда
// Формируем строку из пробелов в зависимости от уровня
Префикс = "";
Для Сч = 1 По Уровень * 3 Цикл
Префикс = Префикс + " ";
КонецЦикла;
// Получаем стандартное представление ссылки
ТекстСсылки = Строка(ДанныеСтроки.Номенклатура);
// Устанавливаем отображаемый текст с пробелами
ОформлениеСтроки.Ячейки.Номенклатура.УстановитьТекст(Префикс + ТекстСсылки);
КонецЕсли;
КонецПроцедуры
Важный нюанс: Чтобы визуальные отступы выглядели ровно, рекомендуется установить для этой колонки моноширинный шрифт (например, Courier New). В противном случае из-за разной ширины символов в пропорциональных шрифтах (Arial, Tahoma) отступы на разных уровнях могут казаться неодинаковыми.
Как было предложено в обсуждении на форуме, можно завести в дереве значений дополнительную колонку Представление с типом Строка. В эту колонку при заполнении дерева записывается наименование объекта с нужным количеством пробелов. При этом основная колонка со ссылкой скрывается, а обработка нажатия (двойного клика) перехватывается с колонки-представления.
Посмотрим на пример заполнения дерева таким способом:
// Пример заполнения дерева из выборки запроса
Пока ВыборкаГТД.Следующий() Цикл
НоваяСтрока = РодительскаяСтрока.Строки.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ВыборкаГТД);
// Формируем визуальный отступ для строковой колонки
Отступ = "";
Для Сч = 1 По НоваяСтрока.Уровень() Цикл
Отступ = Отступ + " ";
КонецЦикла;
НоваяСтрока.Представление = Отступ + Строка(ВыборкаГТД.Номенклатура);
КонецЦикла;
Однако этот метод менее предпочтителен, так как требует ручного управления синхронизацией данных и дополнительной обработки событий для имитации поведения ссылки.
Рассмотрим специфику отображения дерева в обычном приложении. В 1С 8.x (Обычные формы) иерархические связи (значки "+" и "-") и автоматические отступы платформы жестко привязаны к первой видимой колонке табличного поля. Если ваша колонка "Номенклатура" является второй или третьей, платформа не будет рисовать в ней дерево по умолчанию.
Чтобы решить эту проблему, можно использовать следующие приемы:
ОтображатьИерархию = Истина.Проанализируем производительность. Событие ПриВыводеСтроки вызывается платформой каждый раз, когда строка отрисовывается на экране (при скроллинге, обновлении). Поэтому внутри этого события нельзя выполнять тяжелые операции:
ДанныеСтроки.Номенклатура.Код), так как это вызовет неявное обращение к БД. Все данные для вывода должны быть заранее загружены в колонки дерева значений.Использование свойства ОформлениеСтроки.Ячейки.ИмяКолонки.Отступ является наиболее "экономным" для процессора, так как отрисовка отступа выполняется самой платформой на уровне графического движка без изменения текстовых буферов.
Таким образом, мы выяснили, что наиболее эффективным решением задачи заказчика является сочетание события ПриВыводеСтроки и манипуляции свойством Отступ или методом УстановитьТекст(). Это позволяет сохранить целостность данных и обеспечить требуемый визуальный эффект.